Perl 5 - regexp中最长的令牌匹配(使用交替)

时间:2013-02-23 01:13:32

标签: regex perl

可以强制Perl 5正则表达式匹配最长的字符串,如果正则表达式是,例如:

a|aa|aaa

我发现在perl 6中可能是默认值,但在perl 5中,我怎么能得到这种行为?

示例模式:

[0-9]|[0-9][0-9]|[0-9][0-9][0-9][0-9]

如果我有字符串2.10.2014,那么第一场比赛将是2,这是好的;但下一场比赛将是1,这是不行的,因为它应该是10.然后2014年将是4后续比赛2,0,1,4,但它应该是2014年使用[0-9] [0-9] [0-9] [0-9]。我知道我可以使用[0-9] +,但我不能。

4 个答案:

答案 0 :(得分:3)

一般解决方案:先放最长的一个。

my ($longest) = /(aaa|aa|a)/

具体解决方案:使用

my ($longest) = /([0-9]{4}|[0-9]{1,2})/

如果您无法编辑模式,则必须找到所有可能性并找到最长的模式。

my $longest;
while (/([0-9]|[0-9][0-9]|[0-9][0-9][0-9][0-9])/g) {
   $longest = $1 if length($1) > length($longest);
}

答案 1 :(得分:1)

替换将使用匹配的第一个替代方案,因此只需编写/aaa|aa|a/

对于你在问题中显示的例子,就像我说的那样,把最长的替代品放在第一位:

[0-9][0-9][0-9][0-9]|[0-9][0-9]|[0-9]

答案 2 :(得分:1)

我可以看到未知模式的最佳解决方案是匹配每个可能的模式,查看匹配的子串的长度并选择最长的子串:

my @patterns = (qr/a/, qr/a(a)/, qr/b/, qr/aaa/);
my $string = "aaa";

my @substrings = map {$string =~ /($_)/; $1 // ()} @patterns;

say "Matched these substrings:";
say for @substrings;

my $longest_token = (sort { length $b <=> length $a } @substrings)[0];

say "Longest token was: $longest_token";

输出:

Matched these substrings:
a
aa
aaa
Longest token was: aaa

对于已知模式,可以手动对它们进行排序,以使第一次匹配与最长匹配相同:

"aaa" =~ /(aaa|aa|b|a)/;
say "I know that this was the longest substring: $1";

答案 3 :(得分:-1)

perl -Mstrict -Mre=/xp -MData::Dumper -wE'
  {package Data::Dumper;our($Indent,$Sortkeys,$Terse,$Useqq)=(1)x4}
  sub _dump { Dumper(shift) =~ s{(\[.*?\])}{$1=~s/\s+/ /gr}srge }
  my ($count, %RS);
  my $s= "aaaabbaaaaabbab";
  $s =~ m{ \G a+b? (?{ $RS{ $+[0] - $-[0] } //= [ ${^MATCH}, $-[0] ]; $count++ }) (*FAIL) };
  say sprintf "RS: %s", _dump(\%RS);
  say sprintf "count: %s", $count;
'
RS: {
  "1" => [ "a", 0 ],
  "2" => [ "aa", 0 ],
  "3" => [ "aaa", 0 ],
  "4" => [ "aaaa", 0 ],
  "5" => [ "aaaab", 0 ]
}

count: 5