2012-02-16 8 views
6

私は非アクセント付き文字にすべてのアクセント付き文字を変更したい:文字列を辞書に置き換えることはできますか?

conversion_dict = {"ä": "a", "ö": "o", "ü": "u","Ä": "A", "Ö": "O", "Ü": "U", 
        "á": "a", "à": "a", "â": "a", "é": "e", "è": "e", "ê": "e", 
        "ú": "u", "ù": "u", "û": "u", "ó": "o", "ò": "o", "ô": "o", 
        "Á": "A", "À": "A", "Â": "A", "É": "E", "È": "E", "Ê": "E", 
        "Ú": "U", "Ù": "U", "Û": "U", "Ó": "O", "Ò": "O", "Ô": "O","ß": "s"} 

"paragraph of text".replace([conversion_dict])のような何かをする方法はありますか?

+0

なぜ「í」、「Í'、... 'Ï'? – danihp

+0

あなたが示したものは「すべて」ではありません。目的は何ですか? Python 2.xまたは3.xを使用していますか? –

+0

私はこれを行うためのPythonの標準ライブラリに何かがあると信じています: http://www.tutorialsp.com/.com/python/string_translate.htm – user1277476

答えて

8

好ましい方法は、サードパーティのモジュールを使用して

A以下の方法よりもはるかに良い代替手段は素晴らしいunidecodeモジュールを使用することである。

>>> import unidecode 
>>> somestring = u"äüÊÂ" 
>>> unidecode.unidecode(somestring) 
'auEA' 

組み込み、やや危険な方法を

あなたがユニコード文字を正規化しようとしていることをあなたの疑問から推測すると、実際には素晴らしい組み込みの方法がありますこれを行う:

>>> somestring = u"äüÊÂ" 
>>> somestring 
u'\xe4\xfc\xca\xc2' 
>>> import unicodedata 
>>> unicodedata.normalize('NFKD', somestring).encode('ascii', 'ignore') 
'auEA' 

unicodedata.normalizeのドキュメントを参照してください。

ただし、これには問題がある可能性があります。いい説明といくつかの回避策については、this postを参照してください。

他にもlatin-1-to-asciiも参照してください。

+0

これは恐ろしいkludgeです。意図しない副作用を使用していて、ラテン語のテキストを増やすという現実の世界に迷い込んだら、その仕事全体をしません。 –

+1

@JohnMachinあなたは詳細を教えることができますか? – David542

+1

@ JohnMachinか、ちょうどdownvotingより良い代わりを提案することができますか? – jterrace

5
for k, v in conversion_dict.items(): 
    txt = txt.replace(k, v) 

ETA:これはまったく「ひどく」遅くはありません。ここでは、文字のいずれも文字列でなければ56文字のマッピングを持っている辞書を使用して100000文字列を置換しているおもちゃの場合、ためのタイマーです:私のコンピュータで

import timeit 

NUM_REPEATS = 100000 

conversion_dict = dict([(chr(i), "C") for i in xrange(100)]) 

txt = "A" * 100000 

def replace(x): 
    for k, v in conversion_dict.items(): 
     x = x.replace(k, v) 

t = timeit.Timer("replace(txt)", setup="from __main__ import replace, txt") 
print t.timeit(NUM_REPEATS)/NUM_REPEATS, "sec/call" 

私が手ランニング時

0.0056938188076 sec/call 

だから、110万文字列のための第二の二百分の。さて、いくつかの文字は実際に文字列に入りますが、これは遅くなりますが、ほとんどの合理的な状況では、置き換えられた文字は他の文字よりもはるかに稀です。それでも、jterraceの答えは完璧です。

+2

これはひどく遅くなるでしょう。 –

+0

文字列と辞書の長さによって異なります。 –

+0

'replace()'が何かを置き換えなかった場合は、渡した元の文字列を返します。何かを置き換えなければならない場合は、文字列全体をコピー*する必要があります(文字列は不変です)。これはあなたのサンプルコードではまったく起こらないので、あなたのタイミングは意味がありません。 (とにかく、タイミングは通常、2つの異なるアプローチを比較する場合にのみ意味があります) –

0

多分このようなものが動作しますか?私はそれを試していないが、それは簡単な解決策のように思える。

for key in string: 
    if key in dict: 
     string = string.replace(key, dict[key]) 
0

ソースエンコーディングと入力エンコーディングを無視して任意のソリューションは、正式に正しいだろうが、それは簡単にその仕事をして失敗する可能性があります。

まず、入力のエンコーディングを知っていることを確認してから、マップでエンコードしているエンコーディングにマッピングする必要があります。あなたは、内部符号化のユニコードとして使用してと知られている入力エンコーディングを変換することができます。

お試しください。reading this

4

これはVFAQです。例えば、 this SO questionまたはgoogle "python asciify"または "python unaccent"です。

unicode.translateで使用する適切な辞書を作成するには、簡単なケースを自動的に発見し、手動で入力する必要があるものを見つけ出す方法が必要です。良いアプローチは、unicodedata.name(the_ordinal, "")によって何が生産されているかを見て、BMPを徹底的に調べることです。

自動検出:あなたは"LATIN (SMALL|CAPTTAL) LETTER [A-Z].+"との一致を取得する場合re.match("LATIN (SMALL|CAPTTAL) LETTER ([A-Z]) WITH ", name)

はそうしないと、手動で入力する必要があります。

重要な注意:あなたは、例えば交換できるようにunicode.translateが... "Unicodeの序、Unicode文字列またはNoneにUnicodeの序のマッピング" を使用しています首都THORNを "Th"で表します。その正規化の最初の文字がASCIIの範囲にない取り除かれ

文字:unicodedata.normalizeを使用することは良い考えではない理由はここに

です。これにはすべての句読点(あなたが気にしないかもしれない)だけでなく、「アクセント付き」でない文字も含まれます。 ß

>>> from unicodedata import name, normalize 
>>> for i in range(0xA0, 0x100): 
...  c = unichr(i) 
...  a = normalize('NFKD', c).encode('ascii', 'ignore') 
...  if not a: 
...   print("FAIL: U+%04X %s" % (i, name(c))) 
... 
FAIL: U+00A1 INVERTED EXCLAMATION MARK 
FAIL: U+00A2 CENT SIGN 
FAIL: U+00A3 POUND SIGN 
FAIL: U+00A4 CURRENCY SIGN 
FAIL: U+00A5 YEN SIGN 
FAIL: U+00A6 BROKEN BAR 
FAIL: U+00A7 SECTION SIGN 
FAIL: U+00A9 COPYRIGHT SIGN 
FAIL: U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK 
FAIL: U+00AC NOT SIGN 
FAIL: U+00AD SOFT HYPHEN 
FAIL: U+00AE REGISTERED SIGN 
FAIL: U+00B0 DEGREE SIGN 
FAIL: U+00B1 PLUS-MINUS SIGN 
FAIL: U+00B5 MICRO SIGN 
FAIL: U+00B6 PILCROW SIGN 
FAIL: U+00B7 MIDDLE DOT 
FAIL: U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK 
FAIL: U+00BF INVERTED QUESTION MARK 
FAIL: U+00C6 LATIN CAPITAL LETTER AE 
FAIL: U+00D0 LATIN CAPITAL LETTER ETH 
FAIL: U+00D7 MULTIPLICATION SIGN 
FAIL: U+00D8 LATIN CAPITAL LETTER O WITH STROKE 
FAIL: U+00DE LATIN CAPITAL LETTER THORN 
FAIL: U+00DF LATIN SMALL LETTER SHARP S <<<<<<<<<<========== ß 
FAIL: U+00E6 LATIN SMALL LETTER AE 
FAIL: U+00F0 LATIN SMALL LETTER ETH 
FAIL: U+00F7 DIVISION SIGN 
FAIL: U+00F8 LATIN SMALL LETTER O WITH STROKE 
FAIL: U+00FE LATIN SMALL LETTER THORN 
>>> 
関連する問題