gpt4 book ai didi

正则表达式匹配最长的重复子串

转载 作者:行者123 更新时间:2023-12-03 22:28:54 25 4
gpt4 key购买 nike

我正在编写正则表达式来检查是否有一个子字符串,该子字符串包含至少 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

使用当前表达式(使用相同的字符串)我会得到什么:
no pattern - no match
pattern 2 - match
pattern 555 - match
pattern 1919 - match
pattern 191919 - match
pattern 23 - match

最佳答案

在 Perl 中,您可以借助 (??{ code }) 用一个表达式来完成。 :

$_ = '01011010';
say /(?=(.+)\1)(?!(??{ '.+?(..{' . length($^N) . ',})\1' }))/;

输出:
101

这里发生的事情是,在匹配连续的一对子串之后,我们使用负前瞻确保它后面不再有对。

为了使较长对的表达式使用延迟的子表达式构造 (??{ code }) ,它计算内部代码(每次)并使用返回的字符串作为表达式。

它构造的子表达式的形式为 .+?(..{N,})\1 ,其中 N 是第一个捕获组的当前长度( length($^N)$^N 包含前一个捕获组的当前值)。

因此,完整的表达式将具有以下形式:
(?=(.+)\1)(?!.+?(..{N,})\2}))

与神奇 N (并且第二个捕获组不是原始表达式的“真实”/正确捕获组)。

Usage example :
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';

输出:
101
10001
191919
101

关于正则表达式匹配最长的重复子串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9216783/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com