加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

正则表达式 – 匹配Perl中第n个可能的最长字符串

发布时间:2020-12-13 21:52:49 所属栏目:百科 来源:网络整理
导读:Perl正则表达式的模式匹配量词是“贪婪的”(它们匹配最长的可能字符串).为了迫使比赛“不合适”,一个?可以附加到模式量词(*,). 这是一个例子: #!/usr/bin/perl$string="111s22222s";#-- greedy match$string =~ /^(.*)s/;print "$1n"; # prints 111s22222
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引入了一个更改/(?{})/ and /(??{})/ have been heavily reworked,它使词法变量的范围在上面使用的代码表达式中正常工作.在此之前,上述代码将导致以下错误,如this subroutine version run under 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.这在modified subroutine version run under v5.16.2中进行了演示,或者如下所示:

local our @seqs;
$string =~ /^(.*)s(?{push @seqs,$1})(*FAIL)/;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读