Python 最短重复子串
我正在寻找一种有效的方法来提取最短的重复子字符串。 例如:Python 最短重复子串,python,regex,string-matching,Python,Regex,String Matching,我正在寻找一种有效的方法来提取最短的重复子字符串。 例如: input1 = 'dabcdbcdbcdd' ouput1 = 'bcd' input2 = 'cbabababac' output2 = 'ba' 如果您能提供与此问题相关的任何答案或信息,我将不胜感激 此外,在中,人们建议我们可以使用正则表达式,如 re=^(.*?)\1+$ 查找字符串中最小的重复模式。但是这样的表达式在Python中不起作用,并且总是返回一个不匹配的结果(我是Python新手,也许我错过了什么?) ---
input1 = 'dabcdbcdbcdd'
ouput1 = 'bcd'
input2 = 'cbabababac'
output2 = 'ba'
如果您能提供与此问题相关的任何答案或信息,我将不胜感激
此外,在中,人们建议我们可以使用正则表达式,如
re=^(.*?)\1+$
查找字符串中最小的重复模式。但是这样的表达式在Python中不起作用,并且总是返回一个不匹配的结果(我是Python新手,也许我错过了什么?)
---跟进---
这里的标准是寻找长度大于1且总长度最长的最短非重叠图案。此图案的快速修复方法可能是
(.+?)\1+
您的正则表达式失败,因为它将重复字符串锚定到行的开头和结尾,只允许像abcabc
这样的字符串,但不允许xabcabcx
。此外,重复字符串的最小长度应该是1,而不是0(或者任何字符串都会匹配),因此+?
而不是*?
在Python中:
>>> import re
>>> r = re.compile(r"(.+?)\1+")
>>> r.findall("cbabababac")
['ba']
>>> r.findall("dabcdbcdbcdd")
['bcd']
但是请注意,这个正则表达式只会找到非重叠的重复匹配,因此在上一个示例中,将找不到解决方案d
,尽管这是最短的重复字符串。或者查看此示例:此处无法找到abc
,因为第一个abc
的abc
部分已在第一次匹配中用完):
此外,它可能会返回多个匹配项,因此您需要在第二步中找到最短的匹配项:
>>> r.findall("abcdabcdabcabc")
['abcd', 'abc']
更好的解决方案:
要使引擎也能找到重叠的匹配项,请使用
(.+?)(?=\1)
如果某些字符串重复足够多次,则会找到两次或更多,但肯定会找到所有可能的重复子字符串:
>>> r = re.compile(r"(.+?)(?=\1)")
>>> r.findall("dabcdbcdbcdd")
['bcd', 'bcd', 'd']
因此,应按长度对结果进行排序,并返回最短的结果:
>>> min(r.findall("dabcdbcdbcdd") or [""], key=len)
'd'
或[“”]
(感谢J.F.Sebastian!)确保如果根本不存在匹配项,则不会触发任何值错误。^
在字符串开头匹配。在您的示例中,重复的子字符串不是从开头开始的。类似于$
。没有^
和$
时,模式*?
始终匹配空字符串:
虽然它找不到最短的子字符串。“最短”是如何找到的?重复次数最少?“abcabc ababab”怎么样?“阿巴”?第一个字符串中的“dd”?部分匹配使得这个定义有点奇怪…没错。在第一个字符串中,d
应该是正确的答案。是的,我在那里添加了标准。我认为下面的两个答案都可以引导我找到最终的解决方案。谢谢。
>>> min(r.findall("dabcdbcdbcdd") or [""], key=len)
'd'
import re
def srp(s):
return re.search(r'(.+?)\1+', s).group(1)
print srp('dabcdbcdbcdd') # -> bcd
print srp('cbabababac') # -> ba