Rav*_*ven 14 regex perl pattern-matching
我正在编写正则表达式来检查是否存在子串,其中包含至少2个彼此相邻的模式重复.我将正则表达式的结果与前一个字符串相匹配 - 如果相等,则存在这样的模式.通过示例更好地说:1010包含模式10,并且连续系列中有2次.另一方面,10210将不具有这种模式,因为那些10不相邻.
更重要的是,我需要找到最长的模式,它的长度至少为1.我已经写了表达式来检查它^.*?(.+)(\1).*?$.为了找到最长的模式,我使用了非贪婪的版本来匹配模式之前的东西,然后模式匹配到组1并且再次匹配组1匹配的相同的东西.然后匹配其余的字符串,产生相等的字符串.但是有一个问题是正则表达式在找到第一个模式后急于返回,并且没有真正考虑到我打算在最短的时间之前和之后制作那些子串(剩下最长的可能).所以从字符串01011010我得到正确的匹配,但存储在组1中的模式只是01我除了101.
因为我相信我不能让模式"更贪婪"或者在"更多非贪婪"之前和之后变废为止,我只能想出一个让正则表达式不那么渴望的想法,但我不确定这是否可行.
更多例子:
56712453289 - no pattern - no match with former string
22010110100 - pattern 101 - match with former string (regex resulted in 22010110100 with 101 in group 1)
5555555 - pattern 555 - match
1919191919 - pattern 1919 - match
191919191919 - pattern 191919 - match
2323191919191919 - pattern 191919 - match
Run Code Online (Sandbox Code Playgroud)
使用当前表达式会得到什么(使用相同的字符串):
no pattern - no match
pattern 2 - match
pattern 555 - match
pattern 1919 - match
pattern 191919 - match
pattern 23 - match
Run Code Online (Sandbox Code Playgroud)
Qta*_*tax 13
在Perl中,您可以通过以下方式使用一个表达式来完成(??{ code }):
$_ = '01011010';
say /(?=(.+)\1)(?!(??{ '.+?(..{' . length($^N) . ',})\1' }))/;
Run Code Online (Sandbox Code Playgroud)
输出:
101
Run Code Online (Sandbox Code Playgroud)
这里发生的事情是,在匹配连续的一对子串之后,我们确保使用负向前瞻,即不再有一对跟随它.
为了使较长对的表达式使用一个推迟的子表达式构造(??{ code }),它在内部(每次)评估代码并使用返回的字符串作为表达式.
它构造子表达式具有形式.+?(..{N,})\1,其中N是所述第一捕获组的当前长度(length($^N),$^N包含以前捕获组的电流值).
因此,完整表达式将具有以下形式:
(?=(.+)\1)(?!.+?(..{N,})\2}))
Run Code Online (Sandbox Code Playgroud)
神奇的N(和第二个捕获组不是原始表达的"真实"/适当的捕获组).
用法示例:
use v5.10;
sub longest_rep{
$_[0] =~ /(?=(.+)\1)(?!(??{ '.+?(..{' . length($^N) . ',})\1' }))/;
}
say longest_rep '01011010';
say longest_rep '010110101000110001';
say longest_rep '2323191919191919';
say longest_rep '22010110100';
Run Code Online (Sandbox Code Playgroud)
输出:
101
10001
191919
101
Run Code Online (Sandbox Code Playgroud)