Подтвердить что ты не робот

RegExp соответствует повторяющимся символам

Например, у меня есть строка:

 aacbbbqq

В результате я хочу иметь следующие совпадения:

 (aa, c, bbb, qq)  

Я знаю, что могу написать что-то вроде этого:

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

Но я думаю, что я уродлив и ищу лучшего решения. Я ищу решение для регулярного выражения, а не самозаписывающиеся конечные машины.

4b9b3361

Ответ 1

Вы можете сопоставить это с помощью: (\w)\1*

Ответ 2

itertools.groupby не является RexExp, но он не является самозаписываемым.:-) Цитата из python docs:

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

Ответ 3

Вообще

Фокус в том, чтобы соответствовать одному char диапазона, который вы хотите, а затем убедитесь, что вы сопоставляете все повторения одного и того же символа:

>>> 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
²²

\w для строк, не относящихся к Unicode/bytearrays, может быть изменен, если вы впервые выпустили вызов locale.setlocale.

Ответ 5

Метод findall будет работать, если вы захватите обратную ссылку следующим образом:

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

Ответ 6

Вы можете использовать:

re.sub(r"(\w)\1*", r'\1', 'tessst')

Вывод будет:

'test'