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
我自己的版本(对Gumbo进行了稍微优化):
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
最佳答案
这是一个幼稚的算法:
使用索引逐字符遍历原始字符串,并为每个索引检查搜索字符串之一是否等于当前索引之后的字符串。如果找到匹配项,则将替换项插入缓冲区,然后按匹配的字符串的长度进行索引。如果找不到匹配项,则将索引加1。最后,将缓冲区中的字符串连接为单个字符串。
def strtr(strng, replace):
buffer = []
i, n = 0, len(strng)
while i < n:
match = False
for s, r in replace.items():
if strng[i:len(s)+i] == s:
buffer.append(r)
i = i + len(s)
match = True
break
if not match:
buffer.append(strng[i])
i = i + 1
return ''.join(buffer)
关于python - 适用于python的php strtr,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10931150/