从Python中删除字符串中的特定重复字符

时间:2018-04-06 14:50:23

标签: python string python-3.x text set

如果只能在Python中一个接一个地删除字符串中的特定重复字符,我该怎么办?例如:

有字符串

string = "Hello _my name is __Alex"

我需要删除重复_只有当它们一个接一个__并得到这样的字符串时才会删除:

string = "Hello _my name is _Alex"

如果我使用set我得到了这个:

string = "_yoiHAemnasxl"

2 个答案:

答案 0 :(得分:2)

(大编辑:哎呀,我错过了你只想让某些角色去重复,而不是其他人。改造解决方案......)

我假设您有一个字符串,表示您要删除的所有字符。我们称之为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)引用与指定组匹配的字符&#34; char&#34;。
  • +匹配该字符的一个或多个重复。

总而言之,这意味着&#34;匹配to_remove中连续出现多次的任何字符&#34;。 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:为to_remove的每个成员调用re.sub一次。如果to_remove包含很多字符,则有点贵。

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

答案 1 :(得分:1)

简单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