1

辞書を使用して複数の文字列を翻訳しようとしています。ただし、常に個々の文字が置き換えられ、コードを微調整する方法がわかりません。

私の辞書:

{"You're": "I'm", "We've": "you've", 'am': 'are', "We'll": "you'll", 'im': "you're",
"we'd": "you'd", 'our': 'your', 'You': 'I', 'Was': 'were', 'your': 'my', "you're":
"I'm", 'We': 'you', "I've": "you've", "we've": "you've", 'This': 'that', "we're":
"you're", 'you': 'I', 'was': 'were', 'me': 'you', 'we': 'you', 'I': 'you', 'c': 'see',
"I'd": "you'd", 'Were': 'was', "I'm": "you're", 'My': 'your', "I'll": "you'll", "we'll":
"you'll", 'this': 'that', 'Am': 'are', 'ur': "I'm", 'i': 'you', 'u': 'me', "We'd":
"you'd", 'were': 'was', 'Our': 'your', "i'm": "you're", 'my': 'your', 'Your': 'my',
"We're": "you're"}

私のコード:

def replace_all(text, dic):
    for i, j in dic.iteritems():
        text = text.replace(i, j)
    return text

後で次のように呼び出されます。

message = replace_all(message, dictionary)

文字列内の単語全体を置き換えることは可能ですか? 私はPythonに非常に慣れていないので、どんな助けでも大歓迎です!

4

1 に答える 1

4

ブレンダーの答えは、置換が重複しない場合は問題なく機能しますが、次のような置換がある場合 (そうします):

{'I': 'you', 'you': 'I'}

その後、以前の置換が再び置換されますが、これは望ましくありません。彼の答えを少し拡張すると、次のことが修正されます。

import re

def replace_all(text, dic):
    words = sorted(dic, key=len, reverse=True)
    return re.sub('\\b(' + '|'.join(map(re.escape, words)) + ')\\b',
                  lambda m: dic[m.group(0)], text)

これは、最初に次のような正規表現を作成することで機能します。

\b(you|I)\b

モジュールのドキュメントで説明されているre\bように、は「単語境界」を表します1。そのため、単語境界の内部のみに一致します。|は、正規表現の括弧で囲まれた部分内の複数の選択肢を示します。Python は最初の選択肢が一致するとすぐに停止するため、選択肢を長さで逆ソートする必要があります。の前だった場合I、たとえば の前に常に一致するため、一致I'mすることはありません。I'mII'm

そのため、その正規表現を に渡します。これはre.sub、置換文字列だけでなく、より複雑なロジックを可能にする代わりにfunctionを置換することができます。この関数は、一致したテキストを辞書で検索し、そのキーに関連付けられた値を、置き換えるテキストとして返します。

1残念ながら、「単語」の定義は、括弧に関しては知的ではありません。

>>> replace_all("I'm not convinced.", {"I": "you"})
"you'm not convinced."

さいわい、並べ替えたので、最長の一致が常に最初に発生します。

>>> replace_all("I'm not convinced.", {"I": "you", "I'm": "you're"})
"you're not convinced."
于 2013-04-06T22:28:03.703 に答える