我有以下perl代码:
use Data::Dumper;
$key = 'foobar:foo:bar';
$pattern = '^[^:]+:([a-z]{3}):(.+)$';
my @matches = $key =~ /$pattern/i;
print Dumper(@matches);
输出:
$VAR1 = 'foo';
$VAR2 = 'bar';
或者我可以print $1
作为第一个捕获组,$2
作为第二个捕获组。
我想知道的是如何获得完整的模式匹配。例如在PHP中,如果我使用preg_match
,我会得到这个:
Array
(
[0] => foobar:foo:bar
[1] => foo
[2] => bar
)
第一个元素(或$ 0或\ 0)是完全匹配。我如何在Perl中获得这个?
答案 0 :(得分:5)
用括号开始和结束正则表达式,并使整个表达式成为另一个捕获组。
my @matches = $key =~ /($pattern)/i;
print Dumper( ["foobar:foo:bar"=~/$pattern/i] );
$VAR1 = [
'foo',
'bar'
];
print Dumper( ["foobar:foo:bar"=~/($pattern)/i] );
$VAR1 = [
'foobar:foo:bar',
'foo',
'bar'
];
答案 1 :(得分:2)
您可以使用$&
或${^MATCH}
变量,但在5.20之前的Perl版本中存在性能损失(对$&
非常重要)。来自perldoc perlvar
:
- $ MATCH
- $&安培;
与上一次成功模式匹配匹配的字符串(不计算BLOCK中隐藏的任何匹配或当前BLOCK包含的
eval()
)。[...]
- $ {^ MATCH}
这类似于
$&
($MATCH
),除了它不会导致与该变量相关的性能损失。[...]
在Perl v5.18及更早版本中,只保证在使用
/p
修饰符编译或执行模式时返回定义的值。在Perl v5.20中,/p
修饰符不执行任何操作,因此${^MATCH}
与$MATCH
的功能相同。此变量已在Perl v5.10.0中添加。
再次来自perldoc perlvar
:
传统上在Perl中,在代码中的任何位置使用任何三个变量
$`
,$&
或$'
(或其use English
等价物)中的任何一个都会导致随后的所有变量成功模式匹配以制作匹配字符串的副本,以防代码随后访问其中一个变量。这对整个程序造成了相当大的性能损失,因此一般不鼓励使用这些变量。[...]
在Perl 5.10.0中,引入了
/p
匹配运算符标记以及${^PREMATCH}
,${^MATCH}
和${^POSTMATCH}
变量,这使您只能受到惩罚标有/p
的模式。在Perl 5.18.0以后,perl开始分别注意三个变量中每个变量的存在,并且只复制了所需字符串的那部分;所以在
$`; $&; "abcdefgh" =~ /d/
perl只会复制字符串的“abcd”部分。这可能会在
等方面产生重大影响$str = 'x' x 1_000_000; $&; # whoops $str =~ /x/g # one char copied a million times, not a million chars
在Perl 5.20.0中,默认情况下启用了一个新的写时复制系统,它最终修复了这三个变量的所有性能问题,并使它们可以安全地在任何地方使用。
perl -wE 'say for "foo:bar" =~ /^(\w+):(\w+)$/p; say ${^MATCH}'
foo
bar
foo:bar