Longest Match
不幸的是,没有独特的逻辑来告诉正则表达式
引擎以获得尽可能长的匹配。
这样做会/可能会创建一个疯狂的级联回溯情节。
顾名思义,这是一种过于复杂而无法处理的问题。
所有正则表达式都是从左到右处理的。
引擎可以匹配的任何东西首先它会匹配,然后退出。
对于交替来说尤其如此,this|this is|this is here
将始终首先匹配“this is here”并且
永远不会匹配 this is 或 this is here
一旦您意识到这一点,您可以将交替重新排序为
this is here|this is|this,它每次都会给出最长的匹配。
当然可以简化为this(?:(?: is)? here)?
这是获得最长匹配的聪明方法。
还没有看到任何你想组合的正则表达式的例子,
所以这只是一些一般信息。
如果您显示您尝试组合的正则表达式,更好的解决方案可能是
提供。
替换内容确实相互影响,以及之前的任何内容或
跟随集群可能会对匹配的交替产生影响。
如果您有更多问题,请尽管提问。
附录:
对于@Laurel。这总是可以使用 Perl 5 正则表达式 (>5.10)
因为 Perl 可以从正则表达式子表达式中运行代码。
由于它可以运行代码,它可以计算并获得最长的匹配。
然而,最左的规则永远不会改变。
如果正则表达式是热力学,这将是第一定律。
Perl 是一个奇怪的实体,因为它试图在正则表达式之间创建协同作用
和代码执行。
因此,可能会重载它的运算符,以注入
自定义到语言本身。
他们的正则表达式引擎没有什么不同,并且可以以相同的方式进行定制。
所以,理论上,下面的正则表达式可以做成一个正则表达式结构,
一个新的 Alternation 构造。
我不会在这里详细介绍,但我只想说,它不适合胆小的人。
如果您对这类事情感兴趣,请参阅
下的 perlre 手册页
“创建自定义 RE 引擎”部分
Perl:
注意 - 正则表达式替换形式基于 @Laurel complex 示例
(a|ab.*c|.{0,2}c*d) 应用于 abcccd。
在视觉上,如果做成自定义的正则表达式结构,看起来类似于
一个交替(?:rx1||rx2||rx3),我猜这就是很多
Perl6 是通过将正则表达式引擎直接集成到语言中来完成的。
此外,如果按原样使用,则可以根据需要动态构造此正则表达式。
请注意,Perl 正则表达式构造的所有 丰富性 都是可用的。
输出
Longest Match Found: abcccd
代码
use strict;
use warnings;
my ($p1,$p2,$p3) = (0,0,0);
my $targ = 'abcccd';
# Formatted using RegexFormat7 (www.regexformat.com)
if ( $targ =~
/
# The Alternation Construct
(?=
( a ) # (1)
(?{ $p1 = length($^N) })
)?
(?=
( ab .* c ) # (2)
(?{ $p2 = length($^N) })
)?
(?=
( .{0,2} c*d ) # (3)
(?{ $p3 = length($^N) })
)?
# Check At Least 1 Match
(?(1)
(?(2)
(?(3)
| (?!)
)
)
)
# Consume Longest Alternation Match
( # (4 start)
(?(?{
$p1>=$p2 && $p1>=$p3
})
\1
| (?(?{
$p2>=$p1 && $p2>=$p3
})
\2
| (?(?{
$p3>=$p1 && $p3>=$p2
})
\3
)
)
)
) # (4 end)
/x ) {
print "Longest Match Found: $4\n";
} else {
print "Did not find a match!\n";
}