哪个是替换被复制转义的字符的最pythonic方式?

时间:2012-04-27 19:04:39

标签: python replace

我正在寻找以下自解释代码的pythonic和有效替代品:

term = "< << >" # turn this into "( < )"
term.replace("<<", "#~").replace(">>", "~#").replace(">", ")").replace("<", "(").replace("#~", "<").replace("~#", ">")

有什么想法吗?

4 个答案:

答案 0 :(得分:3)

使用正则表达式:

import re
d = {'<': '(', '>': ')'}
replaceFunc = lambda m: m.group('a') or d[m.group('b')]
pattern = r"((?P<a><|>)(?P=a)|(?P<b><|>))"
term = "< << >"

replaced = re.sub(pattern, replaceFunc, term) #returns "( < )"
根据Niklas B的建议

编辑

上述正则表达式相当于匹配:

("<<" OR ">>") OR ("<" OR ">")

(?P<a><|>) #tells the re to match either "<" or ">", place the result in group 'a'
(?P=a) #tells the re to match one more of whatever was matched in the group 'a'
(?P<b><|>) #tells the re to match a sing "<" or ">" and place it in group 'b'

实际上,lambda函数replaceFunc只是重复这个匹配序列,但返回相关的替换字符。

re首先匹配&#34;最大的群组&#34;,因此"<<< >"将转换为"<( )"

答案 1 :(得分:2)

这是比我的第一个答案更短的方法。它将双倍字符序列上的输入拆分以删除它们,然后使用替换单个字符再次将这些段连接起来。和以前一样,它使用字典来指定应该进行的替换。

def convert(s, replacements):
    for before, after in replacements.items():
        s = before.join([segment.replace(before, after) for segment in s.split(before + before)])
    return s

>>> convert('< << >', {'<': '(', '>': ')'})
'( < )'

答案 2 :(得分:1)

我将所有替换术语放在一个列表中,然后迭代并替换:

CHARS = [
  ('<<', '#~'),
  ('>>', '~#'),
  ...
]

for replace in CHARS:
   term = term.replace(*replace)

不确定它是否是最pythonic,但似乎很清楚。你甚至可以考虑接收字符列表的forloop。

答案 3 :(得分:0)

我不确定Pythonic是怎么回事,但它起作用且非常灵活。

def convert(s, replacements):
    pending_char = None
    result = []
    for c in s:
        if c in replacements:
            if c == pending_char:
                result.append(c)
                pending_char = None
            else:
                pending_char = c
        else:
            if pending_char:
                result.append(replacements[pending_char])
                pending_char = None
            result.append(c)
    if pending_char:
        result.append(replacements[pending_char])
    return ''.join(result)

>>> convert('< << >', {'<': '(', '>': ')'})
'( < )'