Удаление определенных повторяющихся символов из строки в Python

Как я могу удалить определенные повторяющиеся символы из строки, только если они идут один за другим в Python? Например:

Есть строка

string = "Hello _my name is __Alex"

Мне нужно удалить дубликат _, только если они идут один за другим __ и получают такую ​​строку:

string = "Hello _my name is _Alex"

Если я использую набор, я получил это:

string = "_yoiHAemnasxl"
itertools.groupby, наверное, лучший вариант
Chris_Rands 06.04.2018 16:56

Что вы имеете в виду под «конкретными персонажами»?

pault 06.04.2018 16:57

@ Жан-Франсуа Фабр не уверен, что это обман этого вопроса - в этом вопросе OP хочет сохранить один из дублированных символов, где в обмане они удаляют их все. Что-то вроде ответа Романа Перехреста здесь другой и полезный, ИМО.

pault 06.04.2018 17:09

Почему дедуплицируется "_", а не два L в "Hello"? По каким критериям мы решаем, что следует удалить?

Kevin 06.04.2018 17:12
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
4
1 617
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Простой подход re.sub():

import re

s = "Hello _my name is __Alex aa"
result = re.sub(r'(\S)\1+', '\\1', s)

print(result)
  • \S - любой непробельный символ
  • \1+ - обратная ссылка на первую захваченную в скобках группу (одно или несколько вхождений)

Выход:

Helo _my name is _Alex a

О, аккуратно. Это более кратко, чем мой ответ, поскольку я не знал, что вы можете ссылаться на предыдущую группу, не называя ее явно.

Kevin 06.04.2018 17:00

@RomanPerekhrest, оказывается, я мог ошибаться, и ваш первый ответ, возможно, действительно был правильным. Сожалею об ошибке, но это отличное решение!

pault 06.04.2018 17:14
Ответ принят как подходящий

(Большое изменение: упс, я пропустил, что вы хотите дедуплицировать только определенные символы, а не другие. Решения по модернизации ...)

Я предполагаю, что у вас есть строка, представляющая все символы, которые вы хотите исключить из дубликатов. Назовем его to_remove и скажем, что он равен "_.-". Таким образом, будут исключены только символы подчеркивания, точки и дефисы.

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

>>> import re
>>> to_remove = "_.-"
>>> s = "Hello... _my name -- is __Alex"
>>> pattern = "(?P<char>[" + re.escape(to_remove) + "])(?P=char)+"
>>> re.sub(pattern, r"\1", s)
'Hello. _my name - is _Alex'

Быстрая разбивка:

  • ?P<char> присваивает первой группе символическое имя char.
  • мы помещаем to_remove в набор символов, []. Необходимо вызвать re.escape, потому что в противном случае дефисы и другие символы могут иметь особое значение внутри набора.
  • (?P=char) относится к символу, соответствующему названной группе "char".
  • + соответствует одному или нескольким повторениям этого символа.

Таким образом, в совокупности это означает «соответствие любому символу из to_remove, который встречается более одного раза подряд». Второй аргумент sub, r"\1", затем заменяет это совпадение первой группой, состоящей только из одного символа.


Альтернативный подход: напишите выражение генератора, которое принимает только символы, не соответствующие предшествующему им символу.

>>> "".join(s[i] for i in range(len(s)) if i == 0 or not (s[i-1] == s[i] and s[i] in to_remove))
'Hello. _my name - is _Alex'

Альтернативный подход № 2: используйте groupby для определения последовательных одинаковых групп символов, затем объедините значения вместе, используя тестирование принадлежности to_remove, чтобы решить, сколько значений следует добавить.

>>> import itertools
>>> "".join(k if k in to_remove else "".join(v) for k,v in itertools.groupby(s, lambda c: c))
'Hello. _my name - is _Alex'

Альтернативный подход №3: вызовите re.sub один раз для каждого члена to_remove. Немного дороже, если to_remove содержит много символов.

>>> for c in to_remove:
...     s = re.sub(rf"({re.escape(c)})\1+", r"\1", s)
...
>>> s
'Hello. _my name - is _Alex'

Другие вопросы по теме