同一正则表达式中的两个不贪婪模式不匹配最短的子字符串



我正在尝试在不使用 xml 库的情况下删除周围的 xml 标签,只使用正则表达式:

s="<tr></tr><tr><td>stuff</td></tr><tr></tr>"
print re.sub(r'<tr>.*?stuff.*?</tr>',r'stuff_without_first_bounding_tr',s)

它打印:

stuff_without_first_bounding_tr<tr></tr>

我期待:

<tr></tr>stuff_without_first_bounding_tr<tr></tr>

我用了.*?两次,都应该是不贪婪的(应该采取最短的解决方案)为什么只有第二个是不贪婪的?我应该使用什么正则表达式?

您需要使用否定的前瞻断言。

>>> s="<tr></tr><tr><td>stuff</td></tr><tr></tr>"
>>> re.sub(r'<tr>(?:(?!</?tr>).)*stuff(?:(?!</?tr>).)*</tr>',r'stuff_without_first_bounding_tr',s)
'<tr></tr>stuff_without_first_bounding_tr<tr></tr>'

(?:(?!</?tr>).)*首先检查要匹配的字符是否不是<符号,后跟可选的正斜杠和tr>。如果是,那么它将匹配相应的字符。我们都知道*重复上一个令牌零次或多次,因此在匹配每个字符之前将检查条件(?:(?!</?tr>).)*。如果特定字符未能满足条件,则匹配将失败。

最新更新