删除重复的字母,缩写除外
Remove duplicated letters except in abbreviations
只要有更多的字母,我就想从字符串中删除重复的字母。例如,考虑以下列表:
aaa --> it is untouched because all are the same letters
aa --> it is untouched because all are the same letters
a --> not touched, just one letter
broom --> brom
school --> schol
boo --> should be bo
gool --> gol
ooow --> should be ow
我使用以下正则表达式来删除重复项,如下所示:
(?<=[a-zA-Z])([a-zA-Z])+(?=[a-zA-Z])
但是,这在字符串 boo
中失败,它保留为原始 boo
而不是删除双 o。 oow
也会发生同样的情况,它不会减少到 ow
.
你知道为什么 boo
没有被正则表达式带走吗?
您可以将由相同字符组成的整个单词匹配并捕获到一个捕获组中,然后在所有其他上下文中匹配重复的连续字母,并进行相应替换:
import re
text = "aaa, aa, a,broom, school...boo, gool, ooow."
print( re.sub(r'\b(([a-zA-Z])+)\b|([a-zA-Z])+', r'', text) )
# => aaa, aa, a,brom, schol...bo, gol, ow.
参见Python demo and the regex demo。
正则表达式详细信息
\b
- 单词边界
(([a-zA-Z])+)
- 第 1 组:一个 ASCII 字母(捕获到第 2 组),然后同一字母出现一次或多次
\b
- 单词边界
|
- 或
([a-zA-Z])
- 第 3 组:捕获到第 3 组的 ASCII 字母
+
- 在第 3 组中出现一次或多次捕获的字母。
替换是第 1 组和第 3 组值的串联。
要匹配任何 Unicode 字母,请将 [a-zA-Z]
替换为 [^\W\d_]
。
您的正则表达式与 boo 不匹配,因为它搜索前后至少有一个不同字符的重复项。
一种可能性是制作一个更简单的正则表达式来捕获所有重复项,然后在结果是一个字符时还原
def remove_duplicate(string):
new_string = re.sub(r'([a-zA-Z])+', r'', string)
return new_string if len(new_string) > 1 else string
这是一个没有正则表达式的可能解决方案。它速度更快,但它也会删除重复的白色 space 和标点符号。不仅是字母。
def remove_duplicate(string):
new_string = ''
last_c = None
for c in string:
if c == last_c:
continue
else:
new_string += c
last_c = c
if len(new_string) > 1:
return new_string
else:
return string
只要有更多的字母,我就想从字符串中删除重复的字母。例如,考虑以下列表:
aaa --> it is untouched because all are the same letters
aa --> it is untouched because all are the same letters
a --> not touched, just one letter
broom --> brom
school --> schol
boo --> should be bo
gool --> gol
ooow --> should be ow
我使用以下正则表达式来删除重复项,如下所示:
(?<=[a-zA-Z])([a-zA-Z])+(?=[a-zA-Z])
但是,这在字符串 boo
中失败,它保留为原始 boo
而不是删除双 o。 oow
也会发生同样的情况,它不会减少到 ow
.
你知道为什么 boo
没有被正则表达式带走吗?
您可以将由相同字符组成的整个单词匹配并捕获到一个捕获组中,然后在所有其他上下文中匹配重复的连续字母,并进行相应替换:
import re
text = "aaa, aa, a,broom, school...boo, gool, ooow."
print( re.sub(r'\b(([a-zA-Z])+)\b|([a-zA-Z])+', r'', text) )
# => aaa, aa, a,brom, schol...bo, gol, ow.
参见Python demo and the regex demo。
正则表达式详细信息
\b
- 单词边界(([a-zA-Z])+)
- 第 1 组:一个 ASCII 字母(捕获到第 2 组),然后同一字母出现一次或多次\b
- 单词边界|
- 或([a-zA-Z])
- 第 3 组:捕获到第 3 组的 ASCII 字母+
- 在第 3 组中出现一次或多次捕获的字母。
替换是第 1 组和第 3 组值的串联。
要匹配任何 Unicode 字母,请将 [a-zA-Z]
替换为 [^\W\d_]
。
您的正则表达式与 boo 不匹配,因为它搜索前后至少有一个不同字符的重复项。
一种可能性是制作一个更简单的正则表达式来捕获所有重复项,然后在结果是一个字符时还原
def remove_duplicate(string):
new_string = re.sub(r'([a-zA-Z])+', r'', string)
return new_string if len(new_string) > 1 else string
这是一个没有正则表达式的可能解决方案。它速度更快,但它也会删除重复的白色 space 和标点符号。不仅是字母。
def remove_duplicate(string):
new_string = ''
last_c = None
for c in string:
if c == last_c:
continue
else:
new_string += c
last_c = c
if len(new_string) > 1:
return new_string
else:
return string