Python “负前瞻”;选择不带扩展的文件名;

Python “负前瞻”;选择不带扩展的文件名;,python,regex,negative-lookahead,Python,Regex,Negative Lookahead,我需要在href=“xxx”中的所有URL中添加“php”,这些URL不以“php”结尾。 我使用negative lookahead(?!php): 两者都添加了扩展名: href="url.php" href="url.php.php" 为什么消极前瞻不起作用?以下方法确实起作用: In [49]: re.sub(r'href="([^"]*?)([.]php)?"', r'href="\1.php"', 'href="url.php"') Out[49]: 'href="url.php"

我需要在
href=“xxx”
中的所有URL中添加“php”,这些URL不以“php”结尾。
我使用negative lookahead
(?!php)

两者都添加了扩展名:

href="url.php"
href="url.php.php"

为什么消极前瞻不起作用?

以下方法确实起作用:

In [49]: re.sub(r'href="([^"]*?)([.]php)?"', r'href="\1.php"', 'href="url.php"')
Out[49]: 'href="url.php"'

In [50]: re.sub(r'href="([^"]*?)([.]php)?"', r'href="\1.php"', 'href="url"')
Out[50]: 'href="url.php"'
原始regex
(.+?)(?!php)
无法正常工作的原因是它与
url.php
匹配,如下所示:

  • (.+?)
    匹配
    url.php
  • 此时,由于下一个字符是双引号,因此满足了负前瞻性

换句话说,
+?
使用包括扩展名在内的整个文件名,使前瞻成为不可操作。

负前瞻意味着regexp尝试匹配下一个模式,但不使用该模式。您的模式
“(.+?)(?!php)”
匹配1个或多个字符,直到它满足
,然后尝试匹配下一个模式,即
php
。此前瞻将始终失败,因为下一个字符是
,并且由于这是一个负前瞻,整个模式将成功

您需要的是负的lookback(
(?),它将在使用字符后尝试匹配模式。当它满足
”时,lookback模式将尝试根据模式
php
匹配最后3个字符

简而言之,请使用以下模式重试

find = 'href="(.+?)(?<!php)"'

“代码”>查找=“HeRF=”((+)?)(By,它工作。B<代码>查找='HeRF= =([.])*]((.^){ 3 })“‘< /代码>,<代码>替换= r'HeRF= =“1”2。php“< /代码>。但是它很丑陋。”Qiao:新的前瞻性版本有点损坏。考虑它对<代码> HREF=“Q”的作用。
。所以在这种情况下不可能使用简单的前瞻模式,对吗?@Qiao:可能是,可能不是。我不知道。当一个简单的非前瞻性正则表达式完成任务时,为什么会固定在前瞻上?@NPE,这不是防弹的:
href=“([^”]+?)(?这很糟糕:
href=“url.php”someattr=“xxx”
->
href=“url.php”someattr=.php“xxx”
find = 'href="(.+?)(?<!php)"'