perl regex将所有匹配放入包括完全匹配的数组中

sli*_*khi 3 regex perl

我有以下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中获得这个?

mob*_*mob 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'
    ];
Run Code Online (Sandbox Code Playgroud)


Thi*_*Not 3

您可以为此使用$&或变量,尽管在 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 开始分别记录这三个变量的存在,并且只复制所需的字符串部分;所以在

$`; $&; "abcdefgh" =~ /d/
Run Code Online (Sandbox Code Playgroud)

perl 只会复制字符串的“abcd”部分。这可能会对类似的事情产生很大的影响

$str = 'x' x 1_000_000;
$&; # whoops
$str =~ /x/g # one char copied a million times, not a million chars
Run Code Online (Sandbox Code Playgroud)

在 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)