RegExp匹配重复的字符

And*_*rew 26 python regex pattern-matching

例如我有字符串:

 aacbbbqq
Run Code Online (Sandbox Code Playgroud)

结果我想要以下匹配:

 (aa, c, bbb, qq)  
Run Code Online (Sandbox Code Playgroud)

我知道我可以这样写:

 ([a]+)|([b]+)|([c]+)|...  
Run Code Online (Sandbox Code Playgroud)

但我认为我很丑,并寻求更好的解决方案.我正在寻找正则表达式解决方案,而不是自编有限状态机.

Qta*_*tax 38

你可以匹配: (\w)\1*


DrT*_*rsa 22

itertools.groupby不是RexExp,但它也不是自编的.:-)来自python docs的引用:

# [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
Run Code Online (Sandbox Code Playgroud)


tzo*_*zot 16

通常

诀窍是匹配所需范围的单个字符,然后确保匹配相同字符的所有重复:

>>> matcher= re.compile(r'(.)\1*')
Run Code Online (Sandbox Code Playgroud)

这匹配任何单个字符(.),然后匹配它的重复(\1*)(如果有的话).

对于输入字符串,您可以获得所需的输出:

>>> [match.group() for match in matcher.finditer('aacbbbqq')]
['aa', 'c', 'bbb', 'qq']
Run Code Online (Sandbox Code Playgroud)

注意:由于匹配组,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
Run Code Online (Sandbox Code Playgroud)

检查后者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
²²
Run Code Online (Sandbox Code Playgroud)

\w如果您第一次发出locale.setlocale呼叫,则可能会修改非Unicode字符串/字节数组.


Rak*_*kar 5

这将有效,请参见此处的工作示例:http://www.rubular.com/r/ptdPuz0qDV

(\w)\1*
Run Code Online (Sandbox Code Playgroud)


Swi*_*ake 5

如果您像这样捕获反向引用,则 findall 方法将起作用:

result = [match[1] + match[0] for match in re.findall(r"(.)(\1*)", string)]
Run Code Online (Sandbox Code Playgroud)