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的版本似乎是最快的,在更长的字符串上,赢家是解决方案:
# '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)
这是一个天真的算法:
使用索引逐个字符地遍历原始字符串,并检查每个索引是否其中一个搜索字符串等于当前索引中的字符串.如果找到匹配项,请在缓冲区中按下替换项,然后按匹配字符串的长度继续索引.如果未找到匹配项,请按索引处理索引.最后,将缓冲区中的字符串连接到单个字符串.
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)