Perl正则表达式的模式匹配量词为“贪心”(它们与最长的字符串匹配)。要强制比赛“不协调”,是吗?可以附加到模式量词(*,+)。
这是一个例子:
#!/usr/bin/perl
$string="111s11111s";
#-- greedy match
$string =~ /^(.*)s/;
print "$1\n"; # prints 111s11111
#-- ungreedy match
$string =~ /^(.*?)s/;
print "$1\n"; # prints 111
但是,如何在Perl中找到第二,第三和..可能的字符串匹配?举一个简单的例子-如果需要更好的例子。
my $skips = 1;
$string =~ /^(.*)s(?(?{$skips-- > 0})(*FAIL))/;
上面将使用贪婪匹配,但是会导致最大匹配故意失败。如果您想要第3大,则可以将跳过次数设置为2。
如下所示:
#!/usr/bin/perl
use strict;
use warnings;
my $string = "111s11111s11111s";
$string =~ /^(.*)s/;
print "Greedy match - $1\n";
$string =~ /^(.*?)s/;
print "Ungreedy match - $1\n";
my $skips = 1;
$string =~ /^(.*)s(?(?{$skips-- > 0})(*FAIL))/;
print "2nd Greedy match - $1\n";
输出:
Greedy match - 111s11111s11111
Ungreedy match - 111
2nd Greedy match - 111s11111
使用此类高级功能时,重要的是要充分了解正则表达式以预测结果。这种特殊情况有效,因为正则表达式的一端固定为^
。这意味着我们知道每个后续的比赛也比前一场短。但是,如果两端都可以移动,则我们不一定可以预测顺序。
如果是这种情况,那么您将全部找到它们,然后对其进行排序:
use strict;
use warnings;
my $string = "111s11111s";
my @seqs;
$string =~ /^(.*)s(?{push @seqs, $1})(*FAIL)/;
my @sorted = sort {length $b <=> length $a} @seqs;
use Data::Dump;
dd @sorted;
输出:
("111s11111s11111", "111s11111", 111)
v5.18
Perl进行v5.18
了一项更改,/(?{})/
并且/(??{})
/已经进行了大量修改,使词汇变量的范围能够在上述代码表达式中正常工作。在此之前,上述代码将导致以下错误,如在v5.16.2下运行的此子例程版本所示:
Variable "$skips" will not stay shared at (re_eval 1) line 1.
Variable "@seqs" will not stay shared at (re_eval 2) line 1.
RE代码表达式的较早实现的解决方案是在初始化时使用来声明变量our
,并为了进一步的良好编码习惯而对localize
它们进行声明。在v5.16.2下运行的修改后的子例程版本中对此进行了演示,或如下所示:
local our @seqs;
$string =~ /^(.*)s(?{push @seqs, $1})(*FAIL)/;
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句