15

Python 3.3 を使用しています。私は次のことをしたい:

  • e アキュート (é) や o サーカムフレックス (ô) などの特殊なアルファベット文字を基本文字 (ô to 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() は Unicode データを受け取り、それを ASCII 文字 (つまり、0x00 から 0x7F の間の普遍的に表示可能な文字) で表現しようとします。これは、US キーボードを使用する人間が選択するものに近いものです。

結果として得られる 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メソッドはかなり高速である必要があり、セットアップが完了すると、1 回の関数呼び出しですべての要件 (小文字化、アクセント記号の削除、および削除) を処理できますtable


ところで、200K 文字のファイルはそれほど大きくありません。strそのため、ファイル全体を単一の に読み取り、それを 1 回の関数呼び出しで変換する方が効率的です。

于 2013-03-07T02:23:43.747 に答える