15

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

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

这是我到目前为止所拥有的:

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)

我该如何改进呢?效率是一个大问题,特别是因为我目前正在循环内执行操作:

# Pseudocode
for mystring in myfile:
    mystring_modified = # operations described above
    mylist.append(mystring_modified)

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

4

2 回答 2

33
>>> import unicodedata
>>> s='éô'
>>> ''.join((c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn'))
'eo'

还可以查看unidecode

Unidecode 提供的是一条中间道路:函数 unidecode() 获取 Unicode 数据并尝试用 ASCII 字符(即 0x00 和 0x7F 之间的通用显示字符)来表示它,其中选择在两个字符集之间映射时采取的折衷方案是接近拥有美式键盘的人的选择。

生成的 ASCII 表示的质量各不相同。对于源自西方的语言,它应该介于完美和良好之间。另一方面,中文、日文或韩文等语言的音译(即用罗马字母传达文本在其他书写系统中表达的发音)是一个非常复杂的问题,这个图书馆甚至没有尝试解决它。它在上下文无关的逐个字符映射中画线。因此,一个好的经验法则是,您要音译的脚本离拉丁字母越远,音译就会越差。

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

于 2013-03-07T02:12:48.983 回答
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,))

产量

123 foe bar

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

从好的方面来说,该str.translate方法应该相当快,并且一旦table设置好,它就可以在一个函数调用中处理您的所有要求(缩小、删除和删除重音符号)。


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

于 2013-03-07T02:23:43.747 回答