Удалить повторяющиеся символы с помощью регулярных выражений? - PullRequest
11 голосов
/ 01 января 2011

Допустим, я хочу удалить все повторяющиеся символы (определенного символа) в строке с помощью регулярных выражений.Это просто -

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) алгоритма, но я хочуизучить это с помощью регулярных выражений

Ответы [ 2 ]

41 голосов
/ 01 января 2011
>>> import re
>>> re.sub(r'([a-z])\1+', r'\1', 'ffffffbbbbbbbqqq')
'fbq'

() вокруг [a-z] задает группу захвата , а затем \1 ( обратная ссылка ) в шаблоне и замене относятся к содержанию первой группы захвата.

Таким образом, регулярное выражение гласит «найти букву, за которой следует одно или несколько вхождений той же буквы», а затем вся найденная часть заменяется одним вхождением найденной буквы.

На боковой ноте ...

Ваш пример кода просто для a действительно глючит:

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

Вы действительно хотели бы использовать 'a+' для своего регулярного выражения вместо 'a*', поскольку оператор * соответствует вхождению "0 или более" и, таким образом, будет сопоставлять пустые строки между двумя не a символами тогда как оператор + соответствует «1 или более».

1 голос
/ 01 января 2011

В случае, если вы также заинтересованы в удалении дубликатов несмежных вхождений, вы должны обернуть вещи в цикл, например как это

 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'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...