我有一个可能有重复字符模式的字符串,例如
'xyzzyxxyzzyxxyzzyx'
我需要编写一个正则表达式,用它最小的重复模式替换这样的字符串:
'xyzzyxxyzzyxxyzzyx' becomes 'xyzzyx',
'abcbaccbaabcbaccbaabcbaccba' becomes 'abcbaccba'
我有一个可能有重复字符模式的字符串,例如
'xyzzyxxyzzyxxyzzyx'
我需要编写一个正则表达式,用它最小的重复模式替换这样的字符串:
'xyzzyxxyzzyxxyzzyx' becomes 'xyzzyx',
'abcbaccbaabcbaccbaabcbaccba' becomes 'abcbaccba'
使用以下内容:
> re.sub(r'(.+?)\1+', r'\1', 'xyzzyxxyzzyxxyzzyx')
'xyzzyx'
> re.sub(r'(.+?)\1+', r'\1', 'abcbaccbaabcbaccbaabcbaccba')
'abcbaccba'
> re.sub(r'(.+?)\1+', r'\1', 'iiiiiiiiiiiiiiiiii')
'i'
它基本上匹配重复自己的模式 (.+?)\1+,并删除除第一组中捕获的重复模式之外的所有内容 \1。另请注意,在此使用不情愿的限定符,即 +? 将使正则表达式回溯相当多。
DEMO。
由于您需要最小的重复模式,因此以下内容适用于您:
re.sub(r'^(.+?)\1+$', r'\1', input_string)
该 ^ 和 $ 锚点确保你不会在字符串的中间获得匹配,并使用 .+? 而不仅仅是 .+ 您将获得最短的模式(使用类似字符串比较结果 'aaaaaaaaaa')。
试试这个正则表达式模式并捕获第一组:
^(.+?)\1+$
^ 用于开始字符串/行的锚点. 除换行符之外的任何字符+ 量词表示至少1次出现? 做的 + 懒惰而不是贪婪,因此给你最短的模式() 捕获组\1+ 用量词反向引用表示该模式应该
至少重复一次$ 用于字符串/行结尾的锚点在这里测试一下: Rubular
上述解决方案会影响性能的很多回溯。如果你知道这些字符串中不允许哪些字符,那么你可以使用一个否定的characted集来消除回溯。例如,如果不允许空格,那么
^([^\s]+)\1+$