2011-11-06 298 views
2

我有点卡在正则表达式中。我在格式Python正则表达式 - 替换大括号之间的所有字符

{% 'ello %} wor'ld {% te'st %} 

一个字符串,我想逃避仅限未{% ... %}标签之间的撇号,所以预期输出是

{% 'ello %} wor"ld {% te'st %} 

我知道我可以只更换所有的人使用字符串replace函数,但我不知道如何使用正则表达式来匹配那些外部大括号

+0

可你{ % 瘦gies%}巢? – tchrist

回答

5

这可能可以用正则表达式来完成,但它会是一个复杂的。它更容易读写,如果你只是做它直接:

def escape(s): 
    isIn = False 
    ret = [] 
    for i in range(len(s)): 
     if not isIn and s[i]=="'": ret += ["""] 
     else: ret += s[i:i+1] 

     if isIn and s[i:i+2]=="%}": isIn = False 
     if not isIn and s[i:i+2]=="{%": isIn = True 

    return "".join(ret) 
+0

+1:正则表达式在这里是错误的工具。你需要修复你的功能。 *标签中的*不*应该被转义,所以''如果isIn和s [i] ==''“...''应该是''如果不是''''''。 – Blair

+0

好点,谢谢 –

+2

谁downvoted,请你解释为什么。 –

3

只是为了好玩,这是用正则表达式来做到这一点:

>>> instr = "{% 'ello %} wor&quote;ld {% te'st %}" 
>>> re.sub(r'\'(?=(.(?!%}))*({%|$))', r'&quote;', instr) 
"{% 'ello %} wor&quote;ld {% te'st %}" 

它采用了积极的展望既找不到{%或字符串的结尾,以及积极向前的负向预测,以确保它不包含任何%}。

2

如果你想使用正则表达式,你可以像这样做虽然:

>>> s = """'{% 'ello %} wor'ld {% te'st %}'""" 
>>> segments = re.split('(\{%.*?%\})', s) 
>>> for i in range(0, len(segments), 2): 
    segments[i] = segments[i].replace('\'', '"') 

>>> ''.join(segments) 
""{% 'ello %} wor"ld {% te'st %}"" 

与伊赫桑的前瞻的解决方案相比,该有,你可以运行在任何类型的更换或分析的好处段不需要重新运行另一个正则表达式。所以如果你决定替换另一个角色,你可以很容易地在循环中做到这一点。

0

bcloughlan,复活这个问题,因为它有一个没有提到的简单解决方案。 (发现你的问题而做一些研究的一般问题有关how to exclude patterns in regex

这里有一个简单的正则表达式:

{%.*?%}|(\') 

交替的左侧完整{% ... %}标签相匹配。我们将忽略这些匹配。右侧与第1组相匹配并捕获撇号,并且我们知道它们是正确的撇号,因为它们与左侧的表达不匹配。

这个程序演示了如何使用正则表达式(见online demo结果):

import re 
subject = "{% 'ello %} wor'ld {% te'st %}" 
regex = re.compile(r'{%.*?%}|(\')') 
def myreplacement(m): 
    if m.group(1): 
     return """ 
    else: 
     return m.group(0) 
replaced = regex.sub(myreplacement, subject) 
print(replaced) 

参考

  1. How to match pattern except in situations s1, s2, s3
  2. How to match a pattern unless...
相关问题