python - 最短重复子串

标签 python regex string-matching

我正在寻找一种提取最短重复子字符串的有效方法。 例如:

input1 = 'dabcdbcdbcdd'
ouput1 = 'bcd'

input2 = 'cbabababac'
output2 = 'ba'

如果有任何与该问题相关的答案或信息,我将不胜感激。

另外,在 this post , 人们建议我们可以使用像这样的正则表达式

re=^(.*?)\1+$

找到字符串中最小的重复模式。但是这样的表达式在 Python 中不起作用,并且总是返回一个不匹配的结果(我是 Python 的新手,也许我错过了什么?)。

---跟进---

这里的标准是寻找长度大于1且总长度最长的最短非重叠模式。

最佳答案

此模式的快速修复可能是

(.+?)\1+

您的正则表达式失败,因为它将重复字符串锚定到行的开头和结尾,只允许像 abcabcabc 但不允许 xabcabcabcx 这样的字符串。此外,重复字符串的最小长度应为 1,而不是 0(或者任何字符串都匹配),因此 .+? 而不是 .*?

在 Python 中:

>>> import re
>>> r = re.compile(r"(.+?)\1+")
>>> r.findall("cbabababac")
['ba']
>>> r.findall("dabcdbcdbcdd")
['bcd']

但请注意,此正则表达式只会找到非重叠的重复匹配项,因此在最后一个示例中,解决方案 d 将不会找到,尽管它是最短的重复字符串。或者看这个例子:这里它找不到 abcd 因为第一个 abcdabc 部分已经在第一次匹配中用完了) :

>>> r.findall("abcabcdabcd")
['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!)确保在根本没有匹配项的情况下不会触发 ValueError

关于python - 最短重复子串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8633996/

相关文章:

algorithm - 使用 Rabin-Karp 搜索字符串中的多个模式

python - 自动填充 Django 模型字段

python - 为游戏 map (在 Python 中)构建有向图的好策略是什么?

python - 如何使用正则表达式读取访问日志主机?

javascript - 正则表达式在javascript中获取字符串的多个段

javascript - 寻找更好的 javascript 文本匹配评分系统

python - 编辑 MySQLdb Python 中使用的 C 编译器

python - 根据多个条件设置numpy数组的值

java - 如何从我的正则表达式中删除这个字符?

c# - 字符串操作 : How to replace a string with a specific pattern