我有一个可能有重复字符模式的字符串,例如
'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
。另请注意,在这里使用不情愿的限定符 ie+?
会使正则表达式回溯很多。
演示。
由于您想要最小的重复模式,因此以下内容应该适合您:
re.sub(r'^(.+?)\1+$', r'\1', input_string)
和锚确保您不会在字符串的中间找到匹配项,并且通过使用^
而不只是您将获得最短的模式(使用类似的字符串比较结果)。$
.+?
.+
'aaaaaaaaaa'
试试这个正则表达式模式并捕获第一组:
^(.+?)\1+$
^
字符串/行开头的锚点.
除换行符以外的任何字符+
表示至少 1 次出现的量词?
使+
懒惰而不是贪婪,从而为您提供最短的模式()
捕获组\1+
带量词的反向引用表示模式应该至少重复一次$
字符串/行尾的锚点在这里测试它:Rubular
上面的解决方案做了很多影响性能的回溯。如果您知道这些字符串中不允许使用哪些字符,则可以使用否定字符集来消除回溯。例如,如果不允许使用空格,则
^([^\s]+)\1+$