phpには次のstrtr
機能があります。
strtr('aa-bb-cc', array('aa' => 'bbz', 'bb' => 'x', 'cc' => 'y'));
# bbz-x-y
文字列内の辞書キーを対応する値に置き換えますが、(重要) 既に置き換えられた文字列は置き換えません。Pythonで同じことを書く単純な試み:
def strtr(strng, replace):
for s, r in replace.items():
strng = strng.replace(s, r)
return strng
strtr('aa-bb-cc', {'aa': 'bbz', 'bb': 'x', 'cc': 'y'})
xz-x-y
私たちが望んでいないものを返します(bb
再び置き換えられました)。上記の関数を変更して、対応するphpのように動作させるにはどうすればよいですか?
(可能であれば、正規表現のない回答を希望します)。
Upd:ここにいくつかの素晴らしい答えがあります。それらの時間を測定したところ、短い文字列では Gumbo のバージョンが最も速く、長い文字列では勝者がre
解決策であることがわかりました。
# 'aa-bb-cc'
0.0258 strtr_thg
0.0274 strtr_gumbo
0.0447 strtr_kojiro
0.0701 strtr_aix
# 'aa-bb-cc'*10
0.1474 strtr_aix
0.2261 strtr_thg
0.2366 strtr_gumbo
0.3226 strtr_kojiro
私自身のバージョン(わずかに最適化されたガンボのものです):
def strtr(strng, replace):
buf, i = [], 0
while i < len(strng):
for s, r in replace.items():
if strng[i:len(s)+i] == s:
buf.append(r)
i += len(s)
break
else:
buf.append(strng[i])
i += 1
return ''.join(buf)
完全なコードとタイミング: https://gist.github.com/2889181