Python正则表达式 - 替换除大括号之外的所有字符

时间:2011-11-06 22:05:19

标签: python regex

我对正则表达式有点困惑。我有一个格式为

的字符串
{% 'ello %} wor'ld {% te'st %}

我想只转义不在{% ... %}标签之间的撇号,所以预期的输出是

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

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

4 个答案:

答案 0 :(得分: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)

答案 1 :(得分:3)

只是为了好玩,这是使用正则表达式的方法:

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

它使用正向前看来找到{%或字符串的结尾,以及在该正面预测中的负向前瞻,以确保它在期待中不包含任何%}。

答案 2 :(得分: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 %}""

与Ehsan的前瞻解决方案相比,这样做的好处是,您可以对段执行任何类型的替换或分析,而无需重新运行另一个正则表达式。因此,如果你决定替换另一个角色,你可以在循环中轻松完成。

答案 3 :(得分: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...