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

2 投票
4 回答
1295 浏览
提问于 2025-04-17 05:46

我在使用正则表达式时遇到了一点困难。我有一个字符串,格式是这样的:

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

我想要只对那些不在 {% ... %} 标签之间的撇号进行转义,所以我希望得到的结果是:

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

我知道可以通过字符串的 replace 函数把所有撇号都替换掉,但我不知道怎么用正则表达式只匹配那些不在大括号里的撇号。

4 个回答

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

为了好玩,这里有一种用正则表达式的方法:

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

它使用了一种叫做“正向前瞻”的技巧,来查找字符串中的{%或者字符串的结尾。同时,它在这个正向前瞻里面又用了“负向前瞻”,确保在查找的时候不包括任何%}。

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)

撰写回答