我有以下perl代码:
use Data::Dumper;
$key = 'foobar:foo:bar';
$pattern = '^[^:]+:([a-z]{3}):(.+)$';
my @matches = $key =~ /$pattern/i;
print Dumper(@matches);
Run Code Online (Sandbox Code Playgroud)
输出:
$VAR1 = 'foo';
$VAR2 = 'bar';
Run Code Online (Sandbox Code Playgroud)
或者我可以print $1为第一个捕获组,$2第二个.
我想知道的是如何获得完整的模式匹配.例如,如果我使用PHP preg_match,我会得到这个:
Array
(
[0] => foobar:foo:bar
[1] => foo
[2] => bar
)
Run Code Online (Sandbox Code Playgroud)
第一个元素(或$ 0或\ 0)是完全匹配的位置.我如何在Perl中获得这个?
用括号开始和结束正则表达式,并使整个表达式成为另一个捕获组.
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'
];
Run Code Online (Sandbox Code Playgroud)
您可以为此使用$&或变量,尽管在 5.20 之前的 Perl 版本中会有性能损失(对于 来说相当显着)。从:${^MATCH}$&perldoc perlvar
- $匹配
- $&
最后一次成功的模式匹配所匹配的字符串(不包括隐藏在 BLOCK 或
eval()当前 BLOCK 内的任何匹配项)。[...]
- ${^匹配}
这类似于
$&($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 开始分别记录这三个变量的存在,并且只复制所需的字符串部分;所以在
Run Code Online (Sandbox Code Playgroud)$`; $&; "abcdefgh" =~ /d/perl 只会复制字符串的“abcd”部分。这可能会对类似的事情产生很大的影响
Run Code Online (Sandbox Code Playgroud)$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}'
Run Code Online (Sandbox Code Playgroud)
foo
bar
foo:bar
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1151 次 |
| 最近记录: |