使用正则表达式去除重复字符?

17 投票
3 回答
26093 浏览
提问于 2025-04-16 09:16

假设我想用正则表达式去掉字符串中所有重复的字符(比如某个特定的字符)。这很简单 -

import re
re.sub("a*", "a", "aaaa") # gives 'a'

那如果我想把所有重复的字符(比如a和z)替换成各自的字符呢?我该怎么做呢?

import re
re.sub('[a-z]*', <what_to_put_here>, 'aabb') # should give 'ab'
re.sub('[a-z]*', <what_to_put_here>, 'abbccddeeffgg') # should give 'abcdefg'

注意:我知道去掉重复字符的方法可以用哈希表或者某些O(n^2)的算法来更好地解决,但我想用正则表达式来试试。

3 个回答

0

这是一个包含所有类别的解决方案:

re.sub(r'(.)\1+', r'\1', 'aaaaabbbbbb[[[[[')

结果是:

'ab['
3

如果你也想去掉那些不连续出现的重复项,你需要把这些操作放在一个循环里,比如这样做:

 s="ababacbdefefbcdefde"

 while re.search(r'([a-z])(.*)\1', s):
     s= re.sub(r'([a-z])(.*)\1', r'\1\2', s)

 print s  # prints 'abcdef'
54
>>> import re
>>> re.sub(r'([a-z])\1+', r'\1', 'ffffffbbbbbbbqqq')
'fbq'

这里的 () 是用来定义一个 捕获组,而 \1(一个 反向引用)在模式和替换中都指的是第一个捕获组的内容。

所以,这个正则表达式的意思是“找到一个字母,后面跟着一个或多个相同的字母”,然后找到的部分会被替换成只出现一次的那个字母。

顺便提一下...

你给的只包含 a 的示例代码其实有问题:

>>> re.sub('a*', 'a', 'aaabbbccc')
'abababacacaca'

你应该用 'a+' 而不是 'a*',因为 * 这个符号表示“0次或多次”,所以它会匹配两个非 a 字符之间的空字符串,而 + 则表示“1次或多次”。

撰写回答