正则表达式匹配重复字符

37 投票
7 回答
39708 浏览
提问于 2025-04-16 19:19

比如我有一个字符串:

 aacbbbqq

我想要得到以下的匹配结果:

 (aa, c, bbb, qq)  

我知道我可以写一些像这样的东西:

 ([a]+)|([b]+)|([c]+)|...  

但是我觉得这样写不好看,所以我在寻找更好的解决方案。我想要用正则表达式来解决这个问题,而不是自己写有限状态机。

7 个回答

26

itertools.groupby 不是正则表达式,也不是自己写的东西。:-) 这是来自 Python 文档的一句话:

# [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
26

一般来说

这里的窍门是先匹配你想要的字符范围中的一个字符,然后确保匹配到这个字符的所有重复:

>>> matcher= re.compile(r'(.)\1*')

这段代码会匹配任何单个字符(.),然后匹配这个字符的重复出现(\1*),如果有的话。

对于你的输入字符串,你可以得到想要的输出:

>>> [match.group() for match in matcher.finditer('aacbbbqq')]
['aa', 'c', 'bbb', 'qq']

注意:由于使用了匹配组,re.findall 可能无法正确工作。

其他范围

如果你不想匹配 任何 字符,可以相应地修改正则表达式中的 .

>>> matcher= re.compile(r'([a-z])\1*') # only lower case ASCII letters
>>> matcher= re.compile(r'(?i)([a-z])\1*') # only ASCII letters
>>> matcher= re.compile(r'(\w)\1*') # ASCII letters or digits or underscores
>>> matcher= re.compile(r'(?u)(\w)\1*') # against unicode values, any letter or digit known to Unicode, or underscore

可以用它来检查 u'hello²²'(Python 2.x)或 'hello²²'(Python 3.x):

>>> text= u'hello=\xb2\xb2'
>>> print('\n'.join(match.group() for match in matcher.finditer(text)))
h
e
ll
o
²²

在处理非Unicode字符串或字节数组时,使用 \w 可能会受到影响,如果你先调用了 locale.setlocale

47

你可以用这个来匹配:(\w)\1*

撰写回答