【问题标题】:Python re negative lookbehind assertion if following pattern allows repetitions如果以下模式允许重复,则 Python 重新否定后向断言
【发布时间】:2020-07-19 21:55:05
【问题描述】:

如果以下模式允许重复,我无法使用 python re 模块使否定后向断言工作:

import re

ok = re.compile( r'(?<!abc)def' )
print( ok.search( 'abcdef' ) ) 
# -> None (ok)
print( ok.search( 'abc def' ) )
# -> 'def' (ok)

nok = re.compile( r'(?<!abc)\s*def' )
print( nok.search( 'abcdef' ) ) 
# -> None (ok)
print( nok.search( 'abc def' ) )
# -> 'def'. Why???

我的真实案例应用是我想在文件中找到匹配项,前提是匹配项前面没有'function':

# Must match
mustMatch = 'x = myFunction( y )'

# Must not match
mustNotMatch = 'function x = myFunction( y )'

# Tried without success (always matches)
tried = re.compile( r'(?<!\bfunction\b)\s*\w+\s*=\s*myFunction' )
print( tried.search( mustMatch  ) ) 
# -> match
print( tried.search( mustNotMatch  ) )
# -> match as well. Why???

这是限制吗?

【问题讨论】:

  • nok = re.compile( '(?&lt;!abc)\s*def' ) 应该是nok = re.compile( r'(?&lt;!abc)\s*def' )
  • @ChrisCharley,虽然需要使用原始字符串,但模式本身的逻辑也是错误的。
  • @ChrisCharley 谢谢,我已经在问题中更正了它,但正如 JvdV 提到的那样,问题有更深的根源

标签: python negative-lookbehind re


【解决方案1】:

" -> 'def'。为什么???"

嗯,这很合乎逻辑。看看你的模式:(?&lt;!abc)\s*def

  • (?&lt;!abc) - 对前面没有 abc 的位置进行负向后查找,仍然会在字符串中生成除一个位置以外的所有位置
  • \s* - 零个或多个空格
  • def - 几乎匹配 def

因此,返回 def 作为匹配项。为了更清楚地理解这一点,这里有一个小的表示,在负向后看之后仍然有效的位置:

如您所见,仍有 7 个有效位置。并且包含 \s* 不会影响任何事情,因为 * 表示 或更多。

所以首先应用here 解释的内容,然后应用类似(?&lt;!\bfunction\b\s)\w+\s*=\s*myFunction 的模式来检索您的匹配项。不过可能有更简洁的方法。

【讨论】:

  • 感谢您的回答!我天真地认为首先会寻找“主要”模式'\s * def',然后再根据后视条件检查匹配。由于后视模式必须是固定的,但我不知道如何解决我的问题
  • @jxrossel,您可以查看的一件事是在您检索到匹配项后与startswith 核对。另一种选择是首先从多个空格中修剪你的条纹(我想这就是为什么你有s*。所以首先应用解释here,然后应用类似的模式:(^|(?&lt;!\bfunction\b\s))\w+\s*=\s*myFunction 来检索你的匹配项。
  • @jxrossel,完成。祝你未来的努力好运。我很乐意为您提供帮助。
  • 作为更好的选择,知道function 可能只是在开头(带有缩进):(?m)^(?!\s*\bfunction\b).*?myFunction。负前瞻允许不固定的字符串长度,并且可以跟随任何感兴趣的内容。我发现的唯一限制是不能跳过以function 开头的换行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多