2012-04-27 86 views
1

我正在寻找一个Python的和有效的替代以下不言自明的代码:哪种方法可以代替被重复转义的字符?

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

任何想法?

+0

是否每个标记都被空格分开? – 2012-04-27 19:12:29

+3

@MarkRansom公平地说,他正在问一个更好的方法来做到这一点,所以他可能意识到这一点。 – 2012-04-27 19:23:02

+0

@JoelCornett不,这取决于。你让我意识到我遇到了一个问题,因为“(<”应该是一个可能的结果字符串,它需要输入<<<,其中第一个必须转换为一个(以及后面的两个转换为< 。噢,我想我需要重新思考和重新制定我的要求...... – 2012-04-27 20:54:28

回答

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('< << >', {'<': '(', '>': ')'}) 
'(<)' 
+0

哇,很美!而且是Joel代码的两倍。 – 2012-04-27 21:56:50

1

我把我所有的替代项列表中,然后遍历该和替换:如果

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

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

不知道它是最Python的,但似乎非常清楚。你甚至可以考虑收到chars列表的forloop。

+0

我不知道...如果字符串中已经存在'#~',那么也会失败。 – 2012-04-27 19:49:11

+0

@NiklasB。,对,我想消除这种替代。 – 2012-04-27 20:58:16

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 "(<)" 

EDIT每尼古拉斯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' 

实际上,拉姆达函数replaceFunc只是重复此匹配序列,但返回相关替换字符河

这个re匹配“最大的组第一”,所以"<<< >"将被转换为"<()"

+0

他希望输出为'(<)'。 – 2012-04-27 19:37:29

+0

@AshwiniChaudhary:固定 – 2012-04-27 19:49:30

+0

+1它的工作正常。 – 2012-04-27 19:53:56

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('< << >', {'<': '(', '>': ')'}) 
'(<)' 
+0

你没有考虑'> >'? – 2012-04-27 20:05:38

+0

@AshwiniChaudhary,我做了。基于这个问题,我认为''>>''应该转换为'>'',尽管这个例子并没有包含它' – 2012-04-27 20:07:42

+0

这个错误在转换('<>> >',{'<': '(', '>':')'}) 结果是'>)'而不是(>) 但是不用担心,因为这个问题的要求似乎已经改变了。感谢您的努力。 – 2012-04-27 21:24:21

相关问题