有正则表达式尽可能保持匹配吗?

时间:2011-08-14 15:47:52

标签: regex perl

是否有一种方便的方法来编写一个试图匹配尽可能多的 regex 的正则表达式?

示例:

my $re = qr/a ([a-z]+) (\d+)/;

match_longest($re, "a") => ()
match_longest($re, "a word") => ("word")
match_longest($re, "a word 123") => ("word", "123")
match_longest($re, "a 123") => ()

也就是说,$re被认为是正则表达式序列,match_longest尝试匹配此序列的多少。从某种意义上说,匹配永远不会失败 - 这只是一个匹配成功的问题。正则表达式匹配失败后,undef表示不匹配的部分。

我知道我可以编写一个函数,它接受一系列正则表达式并创建一个正则表达式来完成match_longest的工作。以下是该想法的概述:

假设您有三个正则表达式:$r1$r2$r3。执行match_longest工作的单个正则表达式将具有以下结构:

$r = ($r1 $r2 $r3)? | $r1 ($r2 $r3) | $r1 $r2 $r3?

不幸的是,这是正则数的二次方。是否可能更有效率?

3 个答案:

答案 0 :(得分:5)

您可以使用正则表达式

$r = ($r1 ($r2 ($r3)?)?)?

每个正则表达式只包含一次。您也可以在此示例中使用非捕获组(?:...),以免干扰原始正则表达式。

答案 1 :(得分:2)

如果我理解了这个问题,那么使用?的嵌套组应该有效:

my $re = qr/a ((\w+) (\d+)?)?/;

答案 2 :(得分:0)

这个特殊情况可以写成:

m/a (?:(\w+)(?: (\d+))?)?/