正则表达式 – 匹配Perl中第n个可能的最长字符串
Perl正则表达式的模式匹配量词是“贪婪的”(它们匹配最长的可能字符串).为了迫使比赛“不合适”,一个?可以附加到模式量词(*,).
这是一个例子: #!/usr/bin/perl $string="111s22222s"; #-- greedy match $string =~ /^(.*)s/; print "$1n"; # prints 111s22222 #-- ungreedy match $string =~ /^(.*?)s/; print "$1n"; # prints 111 但是如何在Perl中找到第二,第三和……可能的字符串匹配?举一个你的简单例子 – 如果需要更好的一个.
使用
conditional expression,code expression和
backtracking control verbs.
my $skips = 1; $string =~ /^(.*)s(?(?{$skips-- > 0})(*FAIL))/; 以上将使用贪婪匹配,但会导致最大匹配故意失败.如果你想要第三大,你可以设置跳过的数量为2. 演示如下: #!/usr/bin/perl use strict; use warnings; my $string = "111s22222s22222s"; $string =~ /^(.*)s/; print "Greedy match - $1n"; $string =~ /^(.*?)s/; print "Ungreedy match - $1n"; my $skips = 1; $string =~ /^(.*)s(?(?{$skips-- > 0})(*FAIL))/; print "2nd Greedy match - $1n"; 输出: Greedy match - 111s22222s22222 Ungreedy match - 111 2nd Greedy match - 111s22222 使用此类高级功能时,必须充分了解正则表达式以预测结果.这种特殊情况有效,因为正则表达式用^固定在一端.这意味着我们知道每个后续匹配也比前一个短.但是,如果两端都可能发生变化,我们无法预测秩序. 如果是这种情况,那么你找到它们,然后你对它们进行排序: use strict; use warnings; my $string = "111s22222s"; my @seqs; $string =~ /^(.*)s(?{push @seqs,$1})(*FAIL)/; my @sorted = sort {length $b <=> length $a} @seqs; use Data::Dump; dd @sorted; 输出: ("111s22222s22222","111s22222",111) 注意v5.18之前的Perl版本 Perl v5.18引入了一个更改 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代码表达式的较早实现的修复是使用 local our @seqs; $string =~ /^(.*)s(?{push @seqs,$1})(*FAIL)/; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |