我需要一个相当复杂的正则表达式,它将选择单词之间有一个空格并且可以在其中包含“-”符号,但是它不应该选择连续的空格。
'KENEDY JOHN G JR E' 'example' 'D-54'
我尝试了以下正则表达式:
\'([\s\w-]+)\'
但它选择了我不希望它做的连续空白。
我希望表达式选择
'KENEDY JOHN G JR E'
'example'
'D-54'
也许,
\'([\w-]+(?:\s[\w-]+)*)\'
?
编辑
如果不允许前导/尾随破折号(在单词边界上),则应为:
/\'(\w+(?:[\s-]\w+)*)\'/
像这样的表达式应该这样做:
'[\w-]+(?:\s[\w-]+)*'
试试这个:
my $data = "'KENEDY JOHN G JR E' 'example' 'D-54'";
# Sets of
# one or more word characters or dash
# followed by an optional space
# enclosed in single quotes
#
# The outermost ()s are optional. There just
# so i can print the match easily as $1.
while ($data =~ /(\'([\w-]+\s?)+\')/g)
{
print $1, "\n";
}
输出
'KENEDY JOHN G JR E'
'example'
'D-54'
不确定这是否适用于您,因为您专门要求使用正则表达式。但是,如果您希望字符串由两个或多个空格或破折号分隔,您可以使用split
use strict;
use warnings;
use v5.10;
my $str = q('KENEDY JOHN G JR E' 'example' 'D-54');
my @match = split /\s{2,}/, $str;
say for @match;
具有类似功能的正则表达式将是
my @match = $str =~ /(.*?)(?:\s{2,}|$)/g;
请注意,您需要找到 end of line 的边缘情况$
。
使用split
or 通配符的好处.
是您依靠空格来定义字段,而不是字段本身的内容。
您的代码实际上是按原样工作的。
use feature qw( say );
$_ = "'KENEDY JOHN G JR E' 'example' 'D-54'";
say for /\'([\s\w-]+)\'/g;
输出:
KENEDY JOHN G JR E
example
D-54
(如果您也想要引号,请移动括号。)
我会简单地使用
my @data = /'([^']*)'/g;
如果您有任何验证要做,请稍后再做。