【问题标题】:Python regex negative lookbehindPython 正则表达式否定后视
【发布时间】:2011-12-07 19:44:02
【问题描述】:

我们解析由自动化脚本创建的日志。我们关心的一个典型的事情是字符串:'1.10.07-SNAPSHOT (1.10.07-20110303.024749-7)',来自以下行:

15:28:02.115 - INFO   - TestLib: Successfully retrieved build version: '1.11.11-SNAPSHOT (1.11.11-20110303.024749-7)'

问题是,有些日志是手动创建的,用户自己输入这些信息。为了提醒自己格式,他们添加了一个带有模板的对话框:

02:24:50.655 - INFO   - gui: Step Dialog: For test results management purposes, specify the build in which the test is executed in the following format, build version: 'specify version here'
02:25:04.905 - INFO   - gui:     Response: OK
02:25:04.905 - INFO   - gui:     Comments: 'build version: '1.11.11''

我目前的正则表达式是.*[Bb]uild [Vv]ersion:*\s*(?!.*<)'?([^']*)''(?!.*<)' 是我第一次尝试避免这个问题,因为有些用户会写''。不过,这并没有解决上述情况。我认为正确的做法是消极的向后看,如果'Step Dialog' 在线,则不匹配,但根据regexr,我尝试写这似乎失败了我(出于某种原因,它是不让我分享我保存的表单的链接)。我认为消极的lookbehind 看起来像这样:(?<!Step Dialog) 并导致:

`(?<!Step Dialog).*[Bb]uild [Vv]ersion:*\s*(?!.*<)'?([^']*)'`

但出于某种原因,这与上面的第一行和第三行都匹配。

编辑:
'[Bb]' 和 ':\s' 适用于通过使用多个冒号和空格(大写“Build”)以不完全正确的格式输入信息的用户。一般情况下清理此问题的建议表示赞赏,我对正则表达式比较陌生。

【问题讨论】:

    标签: python regex


    【解决方案1】:

    你已经接近了,但它仍然匹配,因为它可以找到一个满足.* 的字符串,而前面没有Step Dialog。正面和负面的断言只会影响直接围绕它们的模式。因此,您必须强制它检查您不想匹配 Step Dialog 的每个字符。

    试试这个:

    `^(?:(?!Step Dialog).)*[Bb]uild [Vv]ersion:*\s*(?!.*<)'?([^']*)'`
    

    现在,它确保^(行首)和[Bb]uild [Vv]ersion之间的每个字符不是字符串Step Dialog

    您会注意到我也将其更改为积极的前瞻,因为它更容易理解正在发生的事情。

    【讨论】:

    • 太好了,非常感谢!我也从中了解到 (?:...) ,这是我之前想知道的功能。
    【解决方案2】:

    您可以通过多种方式做到这一点,但您已经非常接近了。

    `.*(?<!Step Dialog.*)[Bb]uild [Vv]ersion:*\s*(?!.*<)'?([^']*)'`
    `^(?!.*Step Dialog).*[Bb]uild [Vv]ersion:*\s*(?!.*<)'?([^']*)'`
    

    Chriszuma 的模式也应该有效。使用你最喜欢的。如果性能是一个考虑因素,您可以对这三种模式进行基准测试,看看哪个更快。我的感觉是它会以 `.(?)` 开头,但我不能确定。

    编辑:正如 ekhumoro 指出的那样,the Python regex engine requires fixed-length lookbehinds,所以第一个在 Python 中不起作用。不过,第二个应该没问题。

    【讨论】:

    • 这些模式中的第一个会产生编译错误,因为后视不是固定宽度。
    • @ekhumoro - 很好的收获。我忘记了 Python 不喜欢可变宽度的lookbehinds。已编辑
    • 为什么这被否决了?如果仍然不正确,请解释原因。
    猜你喜欢
    • 1970-01-01
    • 2021-11-28
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-17
    相关资源
    最近更新 更多