【问题标题】:How to replace two things at once in a string?如何在一个字符串中一次替换两个东西?
【发布时间】:2011-12-31 07:44:36
【问题描述】:

假设我有一个字符串,"ab"

我想一举将"a" 替换为"b",将"b" 替换为"a"

所以最后,字符串应该是"ba" 而不是"aa""bb" 并且不要使用超过一行。这可行吗?

【问题讨论】:

    标签: python string


    【解决方案1】:

    当你需要交换变量时,比如 xy,一个常见的模式是引入一个临时变量 t 来帮助交换:t = x; x = y; y = t.

    同样的模式也可以用于字符串:

    >>> # swap a with b
    >>> 'obama'.replace('a', '%temp%').replace('b', 'a').replace('%temp%', 'b')
    'oabmb'
    

    这种技术并不新鲜。它在 PEP 378 中被描述为一种在美式和欧式小数分隔符和千位分隔符之间进行转换的方法(例如从 1,234,567.891.234.567,89。Guido 认可这是一种合理的技术。

    【讨论】:

    • 对于任何包含 %temp% 的字符串都会被错误地更改这一事实,大家都同意吗?
    • 我倾向于用像 -_(descriptor)_- 这样的荒谬的东西来做这件事。罗嗦但碰撞的可能性很小。
    • 如果您想要真的模糊字符串,请使用私人使用区域中带有 unicode 字符的东西作为标记(甚至是未定义的字符)。一次偶然遇到多个的机会确实非常渺茫。
    【解决方案2】:
    import string
    "abaababb".translate(string.maketrans("ab", "ba"))
    # result: 'babbabaa'
    

    请注意,这仅适用于一个字符的替换。

    对于更长的子字符串或替换,这有点复杂,但可能有效:

    import re
    
    def replace_all(repls, str):
        # return re.sub('|'.join(repls.keys()), lambda k: repls[k.group(0)], str)                                     
        return re.sub('|'.join(re.escape(key) for key in repls.keys()),
                      lambda k: repls[k.group(0)], str)                                     
    
    
    text =  "i like apples, but pears scare me"
    print replace_all({"apple": "pear", "pear": "apple"}, text)
    

    不幸的是如果你包含任何正则表达式特殊字符,这将不起作用你不能以这种方式使用正则表达式:(

    (感谢@TimPietzcker)

    【讨论】:

    • NVM,明白了。有没有办法为多个角色做到这一点?说我是否想将 a 更改为“广告”?
    • 您可以将任意数量的单个字符替换为其他一些单个字符。如果您想替换字符串(例如,"apple" 替换为 "yummy",而 "pear" 替换为 "clown"),则不合适。
    【解决方案3】:

    如果你对两条线没问题,那就更优雅了。

    d={'a':'b','b':'a'}
    ''.join(d[s] for s in "abaababbd" if s in d.keys())
    

    【讨论】:

    • ''.join(d[s] if s in d else s for s in "abaababbd")
    • @wim 的回答是这里最好的回答。
    • ''.join(d.get(s,s) for s in "abaababbd")
    【解决方案4】:
    >>> import re
    >>> re.sub('.', lambda m: {'a':'b', 'b':'a'}.get(m.group(), m.group()), 'abc')
    'bac'
    

    【讨论】:

      【解决方案5】:

      您的示例有点抽象,但过去我使用过this recipe,它构建了一个正则表达式来进行单遍多次替换。这是我的调整版本:

      import re 
      
      def multiple_replace(dict, text): 
        regex = re.compile("|".join(map(re.escape, dict.keys())))
        return regex.sub(lambda mo: dict[mo.group(0)], text) 
      

      请注意,键(搜索字符串)被重新转义。

      在你的情况下是:

      from utils import multiple_replace
      
      print multiple_replace({
          "a": "b",
          "b": "a"
      }, "ab") 
      

      更新:

      到现在这和Amadan's answer基本一样

      【讨论】:

        【解决方案6】:
        the_string="ab"
        new_string=""
        
        for x in range(len(the_string)):
            if the_string[x]=='a':
                new_string+='b'
                continue
            if the_string[x]=='b':
                new_string+='a'
                continue
            new_string+=the_string[x]
        
        the_string=new_string
        
        print the_string
        

        【讨论】:

        • OP: "并且不要使用超过一行"
        • 好吧,我想我也作弊了,import...:P
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-10
        • 1970-01-01
        • 1970-01-01
        • 2020-01-16
        • 2011-07-01
        相关资源
        最近更新 更多