Python:替换重音的有效方法(é到e),删除[^ a-zA-Z\d\s]和lower()

oyr*_*yra 14 python regex

使用Python 3.3.我想做以下事情:

  • 用基本字符(例如ô到o)替换特殊的字母字符,例如e acute(é)和o circumflex(ô)
  • 删除除字母数字以外的所有字符和字母数字字符之间的空格
  • 转换为小写

这是我到目前为止:

mystring_modified = mystring.replace('\u00E9', 'e').replace('\u00F4', 'o').lower()
alphnumspace = re.compile(r"[^a-zA-Z\d\s]")
mystring_modified = alphnumspace.sub('', mystring_modified)
Run Code Online (Sandbox Code Playgroud)

我怎样才能改善这个?效率是一个大问题,特别是因为我目前正在循环中执行操作:

# Pseudocode
for mystring in myfile:
    mystring_modified = # operations described above
    mylist.append(mystring_modified)
Run Code Online (Sandbox Code Playgroud)

有问题的文件大约每个200,000个字符.

Joh*_*ooy 29

>>> import unicodedata
>>> s='éô'
>>> ''.join((c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn'))
'eo'
Run Code Online (Sandbox Code Playgroud)

还可以查看unidecode

什么Unidecode提供的是一个中间道路:功能unidecode()接收Unicode数据并试图代表它在ASCII字符(即,0×00和0x7F的之间的普遍显示字符),其中,当被选择两个字符集之间的映射所采取的折衷是接近美国键盘人的选择.

结果ASCII表示的质量会有所不同.对于西方语言来说,它应该在完美和良好之间.另一方面,如中文,日文或韩文等语言的音译(即用罗马字母传达由其他书写系统中的文字表达的发音)是一个非常复杂的问题,这个图书馆甚至没有试图解决它.它在无上下文的逐字符映射中绘制线条.因此,一个好的经验法则是,您所翻译的脚本越是拉丁字母,音译就越差.

请注意,此模块通常比仅从字符中剥离重音更能产生更好的结果(可以使用内置函数在Python中完成).它基于手动调整的字符映射,例如还包含符号和非拉丁字母的ASCII近似值.


unu*_*tbu 5

你可以使用str.translate:

import collections
import string

table = collections.defaultdict(lambda: None)
table.update({
    ord('é'):'e',
    ord('ô'):'o',
    ord(' '):' ',
    ord('\N{NO-BREAK SPACE}'): ' ',
    ord('\N{EN SPACE}'): ' ',
    ord('\N{EM SPACE}'): ' ',
    ord('\N{THREE-PER-EM SPACE}'): ' ',
    ord('\N{FOUR-PER-EM SPACE}'): ' ',
    ord('\N{SIX-PER-EM SPACE}'): ' ',
    ord('\N{FIGURE SPACE}'): ' ',
    ord('\N{PUNCTUATION SPACE}'): ' ',
    ord('\N{THIN SPACE}'): ' ',
    ord('\N{HAIR SPACE}'): ' ',
    ord('\N{ZERO WIDTH SPACE}'): ' ',
    ord('\N{NARROW NO-BREAK SPACE}'): ' ',
    ord('\N{MEDIUM MATHEMATICAL SPACE}'): ' ',
    ord('\N{IDEOGRAPHIC SPACE}'): ' ',
    ord('\N{IDEOGRAPHIC HALF FILL SPACE}'): ' ',
    ord('\N{ZERO WIDTH NO-BREAK SPACE}'): ' ',
    ord('\N{TAG SPACE}'): ' ',
    })
table.update(dict(zip(map(ord,string.ascii_uppercase), string.ascii_lowercase)))
table.update(dict(zip(map(ord,string.ascii_lowercase), string.ascii_lowercase)))
table.update(dict(zip(map(ord,string.digits), string.digits)))

print('123 fôé BAR?'.translate(table,))
Run Code Online (Sandbox Code Playgroud)

产量

123 foe bar
Run Code Online (Sandbox Code Playgroud)

在不利方面,您必须列出您要翻译的所有特殊重音字符.@ gnibbler的方法需要较少的编码.

str.translate好的方面来说,该方法应该相当快,并且在设置完成后,它可以在一个函数调用中处理所有要求(下载,删除和删除重音)table.


顺便说一句,200K字符的文件不是很大.因此,将整个文件读入单个文件str然后在一个函数调用中进行翻译会更有效.