查找出现两次且不重叠的最长子串的正则表达式

3 投票
1 回答
1920 浏览
提问于 2025-04-18 05:11

有很多问题是在问如何找到最长的重复子串:

但是这些问题并不完全符合我的要求,具体来说:

  • 子串之间不能重叠(它们是互不相交的)。
  • 子串可以不相邻。
  • 允许任何字符。
  • 我想要匹配的是最长的模式。

到目前为止,我有这个:

>>> m = re.match(".*(?P<grp>.+).*(?P=grp).*", "dhiblhip")
>>> m.group('grp')
'i'

我觉得这个代码匹配的是最后一个重复的子串,也就是 'i',但这显然不是最长的那个。我希望对于以下输入能得到这样的输出:

  • '123abc' -> ''
  • 'hh' -> 'h'
  • 'hihi' -> 'hi'
  • 'dhiblhip' -> 'hi'
  • 'phiblhip' -> 'hi'(注意我不返回 'p',因为它没有 'hi' 长,即使它是一个重复的互不相交的子串。)
  • 'racecaracecar' -> 'raceca'(注意我不能重复使用中间的 r。)在这种情况下,'acecar' 也是可以接受的。

我正在使用 Python 的 re 模块,并希望继续使用它,但其他语言的答案也欢迎。

1 个回答

2

感谢@HamZa提供的正则表达式:(.+)(?=.*\1)。这个表达式的意思是,它会找到一个包含至少一个字符的部分,然后再检查一下后面有没有重复的内容(这样就不会出现Python找不到重叠匹配的问题)。

虽然仅靠正则表达式无法找到最大的匹配项,但写起来其实很简单。

matches = re.findall(r'(.+)(?=.*\1)',yourstring)
largest = '' if not matches else max(matches,key=lambda m:len(m))

撰写回答