正则表达式用于Python中的重音不敏感替换
问题内容:
在Python 3中,我希望能够以re.sub()
“不区分重音”的方式使用,就像我们可以使用re.I
不区分大小写的替换标志一样。
可能像一个re.IGNOREACCENTS
标志:
original_text = "¿It's 80°C, I'm drinking a café in a cafe with Chloë。"
accent_regex = r'a café'
re.sub(accent_regex, 'X', original_text, flags=re.IGNOREACCENTS)
这将导致“¿°C为80°C,我正在用Chloë在X中喝X。”(请注意,“Chloë”仍带有重音符号),而不是“¿¿°C为80°C,我在Chloë中正在X喝X。与Chloë的咖啡馆。
我认为这样的标志不存在。那么什么是最好的选择呢?使用re.finditer
和unidecode
两个original_text
和accent_regex
,然后通过分裂来替换字符串?或accent_regex
通过重音变体来修改中的所有字符,例如:r'[cç][aàâ]f[éèêë]'
?
问题答案:
unidecode
经常被提及用于删除Python中的重音符号,但它的作用还不止于此:它将转换'°'
为'deg'
,这可能不是所需的输出。
unicodedata
似乎具有消除口音的功能。
有任何图案
此方法应适用于任何模式和任何文本。
您可以从文本和正则表达式模式中暂时删除重音。来自re.finditer()
(开始和结束索引)的匹配信息可用于修改原始的带重音符号的文本。
请注意,必须颠倒匹配项才能不修改以下索引。
import re
import unicodedata
original_text = "I'm drinking a 80° café in a cafe with Chloë, François Déporte and Francois Deporte."
accented_pattern = r'a café|François Déporte'
def remove_accents(s):
return ''.join((c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn'))
print(remove_accents('äöüßéèiìììíàáç'))
# aoußeeiiiiiaac
pattern = re.compile(remove_accents(accented_pattern))
modified_text = original_text
matches = list(re.finditer(pattern, remove_accents(original_text)))
for match in matches[::-1]:
modified_text = modified_text[:match.start()] + 'X' + modified_text[match.end():]
print(modified_text)
# I'm drinking a 80° café in X with Chloë, X and X.
如果模式是一个单词或一组单词
你可以 :
- 从模式词中删除重音并将其保存在一组中以便快速查找
- 寻找与您的文字中的每个单词
\w+
- 从单词中删除重音:
- 如果匹配,则替换为
X
- 如果不匹配,则保持原样
- 如果匹配,则替换为
import re
from unidecode import unidecode
original_text = "I'm drinking a café in a cafe with Chloë."
def remove_accents(string):
return unidecode(string)
accented_words = ['café', 'français']
words_to_remove = set(remove_accents(word) for word in accented_words)
def remove_words(matchobj):
word = matchobj.group(0)
if remove_accents(word) in words_to_remove:
return 'X'
else:
return word
print(re.sub('\w+', remove_words, original_text))
# I'm drinking a X in a X with Chloë.