php的strtr for python

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)

完整的代码和时间:https://gist.github.com/2889181

这是一个天真的算法:

使用索引逐个字符地遍历原始字符串,并检查每个索引是否其中一个搜索字符串等于当前索引中的字符串.如果找到匹配项,请在缓冲区中按下替换项,然后按匹配字符串的长度继续索引.如果未找到匹配项,请按索引处理索引.最后,将缓冲区中的字符串连接到单个字符串.

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)

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...