2009-06-02 12 views
6

PHPでは、preg_replace($patterns, $replacements, $string)があります。パターンと置換えの配列を渡すことで、すべての置換を一度に行うことができます。Pythonで文字列を置き換えるときに辞書を渡すことはできますか?

Pythonで同等のものは何ですか?

私はリックによってコメントに基づいて明確にする

編集...文字列と再機能replace()sub()は辞書を取らないことに気づい: アイデアが取られるべきキーを持つ辞書を持つことです'\d+S'のような正規表現パターンと(うまくいけば)定数の文字列値(うまくいけば、後方参照を除く)。それに応じて自分の答えを編集する(つまり、実際の質問に答える)。

答えて

10

最も近いと考えられる:例えば

somere.sub(lambda m: replacements[m.group()], text) 

.getの代わり[] -indexingと

>>> za = re.compile('z\w') 
>>> za.sub(lambda m: dict(za='BLU', zo='BLA')[m.group()], 'fa za zo bu') 
'fa BLU BLA bu' 

あなたはreplacementsに欠けているマッチのデフォルトを供給したい場合。

編集:本当にリックが望むのは、'\d+S'のような正規表現パターンと、一定の文字列値(うまくいけば後方参照あり)などのキーを持つ辞書を持つことです。料理のレシピは、この目的のために適合させることができる。

def dict_sub(d, text): 
    """ Replace in 'text' non-overlapping occurences of REs whose patterns are keys 
    in dictionary 'd' by corresponding values (which must be constant strings: may 
    have named backreferences but not numeric ones). The keys must not contain 
    anonymous matching-groups. 
    Returns the new string.""" 

    # Create a regular expression from the dictionary keys 
    regex = re.compile("|".join("(%s)" % k for k in d)) 
    # Facilitate lookup from group number to value 
    lookup = dict((i+1, v) for i, v in enumerate(d.itervalues())) 

    # For each match, find which group matched and expand its value 
    return regex.sub(lambda mo: mo.expand(lookup[mo.lastindex]), text) 

使用例:

d={'\d+S': 'wot', '\d+T': 'zap'} 
    t='And 23S, and 45T, and 66T but always 029S!' 
    print dict_sub(d, t) 

が発する:

And wot, and zap, and zap but always wot! 

あなたはlookupを構築避け、ちょうどmo.expand(d.values()[mo.lastindex-1])を使用していますが、それはあるかもしれない可能性がdが非常に大きく、一致が多数ある場合は少し遅くなります(申し訳ありませんが、両方のアプローチを正確に測定/ベンチマークしていないので、これはちょうど推測;-)。

replacements = dict(hello='goodbye', good='bad') 
s = "hello, good morning"; 
for old, new in replacements.items(): 
    s = s.replace(old, new) 

あなたは、PHPの関数は、値の配列を受け入れるとは直接Pythonの同等がない多くの場所を見つけるだろうが、配列で動作する方がはるかに簡単です(リスト:

+0

なります

s = "%(hello)s, %(good)s morning" changed_s = s%replacement 

この形式の文字列を記述してい

replacement = {'hello' : 'goodbye', 'good' : 'bad' } 

を、私はあなたができると思います私がActiveStateから手に入れた関数よりも簡単になるのは、実際に置換とパターンの両方が必要な場合です。あなたはできる? –

+0

1回のパスで複数の文字列置換を行うには、そのレシピが好きです。そのため、Python Cookbookのために選択しました。http://books.google.com/books?id=Q0s6Vgb98CQC&pg=PA38&dq=xavier+defrang&ei=k5okSvPbNILClQSk2LWvBw私はディスカッションのアナと私はそこにいくつかの価値を追加すると思うが、私はもちろん偏っている)。私は質問された正確な質問にもっと直接的に答えようとしていました - 完全に一般的なREと置き換えられたdict。 –

+0

PHPのpreg_replaceは多くの正規表現と置換の両方を受け入れるので、オリジナルの質問はレシピによってうまく答えられると思います。 –

-2

これを行うには十分に簡単です)をPythonでコンパイルすると、それほど問題はありません。

+0

あなたがdict.iteritems代わりのdict.itemsを使用する場合があります、PEP290あたりhttp://www.python.org/dev/peps/pep- 0290 /#ルーピング・オーバー・ディクショナリー – NicDumZ

+5

好きではありません。 dict.items()は特定の順序であることが保証されていないため、結果の置換は予測できません。たとえば、あなたの例では、 "hello"が最初に処理された場合、結果の文字列は "badbye、bad morning"です。それ以外の場合は、「さようなら、悪い朝」です。 – Triptych

+0

@トリプティック:いいキャッチ。 –

-1

は、ここでのpythonで文字列を交換しながら、あなたは辞書を渡すことができ

mynewstring=reduce(lambda a,(b,c): a.replace(b, c), mydict.items(), mystring) 
+0

mydictが '{'a': 'b'、 'b': 'a'} ' – Eric

+0

の場合は失敗します。これは簡単であるために支払う代金です。この簡単な方法は、チェインされた置換をシミュレートします。 –

+1

それでもうまくいけないのであれば、シンプルなソリューションは役に立ちません。 – Eric

-2

減らす使用して簡単な方法です。 上記の例考えてみましょう:あなたはchanged_sの出力は、これが唯一の正規表現をサポートしています

"goodbye, bad morning" 
+1

-1:文字列の置換ではなく、文字列の補間です。 – Blair

関連する問題