查找出现两次且不重叠的最长子串的正则表达式
有很多问题是在问如何找到最长的重复子串:
但是这些问题并不完全符合我的要求,具体来说:
- 子串之间不能重叠(它们是互不相交的)。
- 子串可以不相邻。
- 允许任何字符。
- 我想要匹配的是最长的模式。
到目前为止,我有这个:
>>> 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))