11

我有一个可能有重复字符模式的字符串,例如

'xyzzyxxyzzyxxyzzyx'

我需要编写一个正则表达式,用最小的重复模式替换这样的字符串:

'xyzzyxxyzzyxxyzzyx' becomes 'xyzzyx',

'abcbaccbaabcbaccbaabcbaccba' becomes 'abcbaccba'
4

3 回答 3

9

使用以下内容:

> 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+?会使正则表达式回溯很多。

演示

于 2012-09-17T23:54:37.227 回答
4

由于您想要最小的重复模式,因此以下内容应该适合您:

re.sub(r'^(.+?)\1+$', r'\1', input_string)

和锚确保您不会在字符串的中间找到匹配项,并且通过使用^而不只是您将获得最短的模式(使用类似的字符串比较结果)。$.+?.+'aaaaaaaaaa'

于 2012-09-18T00:05:24.003 回答
2

试试这个正则表达式模式并捕获第一组:

^(.+?)\1+$
  • ^字符串/行开头的锚点
  • .除换行符以外的任何字符
  • +表示至少 1 次出现的量词
  • ?使+懒惰而不是贪婪,从而为您提供最短的模式
  • ()捕获组
  • \1+带量词的反向引用表示模式应该至少重复一次
  • $字符串/行尾的锚点

在这里测试它:Rubular


上面的解决方案做了很多影响性能的回溯。如果您知道这些字符串中不允许使用哪些字符,则可以使用否定字符集来消除回溯。例如,如果不允许使用空格,则

^([^\s]+)\1+$
于 2012-09-18T03:13:21.093 回答