仅当它与另一个正则表达式(Python)不匹配时才替换正则表达式

So8*_*res 5 python regex

长话短说,我有两个正则表达式.一种模式匹配我想要替换的内容,另一种模式匹配那些不应替换的模式的特殊情况.举一个简单的例子,假设第一个是"\ {.*\}",第二个是"\ {\ {.*\} \}".然后应该替换"{this}",但不应该"{{this}}".是否有一种简单的方法来取一个字符串并说"用"hello"替换第一个字符串的所有实例,只要它不匹配第二个字符串"?

换句话说,有没有办法在不修改第一个字符串的情况下轻松制作"匹配第一个字符串而不是第二个字符串"的正则表达式?我知道我可以手动修改我的第一个正则表达式,从不匹配第二个正则表达式的实例,但是随着第一个正则表达式变得更加复杂,这变得非常困难.

spb*_*gie 6

使用负前瞻/后方断言

pattern = re.compile( "(?<!\{)\{(?!\{).*?(?<!\})\}(?!\})" )
pattern.sub( "hello", input_string )
Run Code Online (Sandbox Code Playgroud)

负向前瞻/后方断言允许您与更多字符串进行比较,但不会将其视为用尽匹配的字符串的一部分.还有一个正常的前面/后面断言,只有当字符串IS跟随/前面给定的模式时才会使字符串匹配.

这看起来有点令人困惑,在这里它是碎片:

"(?<!\{)"  #Not preceded by a {
"\{"       #A {
"(?!\{)"   #Not followed by a {
".*?"      #Any character(s) (non-greedy)
"(?<!\})"  #Not preceded by a } (in reference to the next character)
"\}"       #A }
"(?!\})"   #Not followed by a }
Run Code Online (Sandbox Code Playgroud)

所以,我们正在寻找一个{没有任何其他的',其次是一些字符,然后是},而没有任何其他}围绕它.

通过使用负向前瞻/后方断言,我们将其压缩为单个正则表达式,该表达式将成功匹配字符串中任何位置的单个{}.

另外,请注意*是一个贪婪的运算符.它将尽可能多地匹配.如果您使用"\{.*\}"并且文本中有多个{}块,则将使用它之间的所有内容.

"这是一些示例文本{block1}更多文字,看着我消失{block2}更多文字"

"这是一些示例文本你好更多的文字"

代替

"这是一些示例文本你好更多的文字,看着我消失你好更多的文字"

为了获得正确的输出,我们需要通过附加?来使其变得非贪婪.

python文档可以很好地呈现re库,但真正学习的唯一方法是进行实验.


Nad*_*mli 4

你可以给replace一个函数(参考

但请确保第一个正则表达式包含第二个正则表达式。这只是一个例子:

regex1 = re.compile('\{.*\}')
regex2 = re.compile('\{\{.*\}\}')

def replace(match):
    match = match.group(0)
    if regex2.match(match):
        return match
    return 'replacement'


regex1.sub(replace, data)
Run Code Online (Sandbox Code Playgroud)