用于在python中重音不敏感替换的正则表达式

时间:2017-04-26 12:39:51

标签: python regex unicode non-ascii-characters accent-insensitive

在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)

这将导致“¿它是80°C,我在Chloë中用X喝X.”(请注意,“Chloë”仍有一个重点而不是“¿它是80°C,我正在喝酒X在Chloë的咖啡馆里。“真正的蟒蛇。

我认为这样的旗帜不存在。那么这样做的最佳选择是什么?在re.finditerunidecode上使用original_textaccent_regex,然后通过拆分字符串来替换?或者通过重音变体修改accent_regex中的所有字符,例如:r'[cç][aàâ]f[éèêë]'

2 个答案:

答案 0 :(得分:8)

unidecode经常被提及用于删除Python中的重音,但它也不仅仅是:它将'°'转换为'deg',这可能不是所需的输出。

unicodedata似乎有enough functionality to remove accents

使用任何模式

此方法适用于任何模式和任何文本。

您可以暂时从文本和正则表达式模式中删除重音符号。来自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.

如果pattern是一个单词或一组单词

你可以:

  • 从您的模式字中删除重音并将其保存在一组中以便快速查找
  • 使用\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ë.

答案 1 :(得分:0)

您可以使用Unidecode

$ pip install unidecode

在你的计划中:

from unidecode import unidecode

original_text = "I'm drinking a café in a cafe."
unidecoded_text = unidecode(original_text)
regex = r'cafe'
re.sub(regex, 'X', unidecoded_text)