Python正则表达式负面看后方

时间:2011-10-14 14:29:21

标签: python regex

我们解析自动脚本创建的日志。我们关心的一个典型事情是来自以下行的字符串:'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*(?!.*<)'?([^']*)''(?!.*<)'是我第一次尝试避免这个问题,因为有些用户会写''。但是,这并没有抓住上述情况。根据{{​​3}},我认为正确的做法是做一个负面的观察,如果'Step Dialog'出现在线上就不匹配,但是我的写作尝试似乎让我失望了。由于某种原因,它不会让我分享我保存的表格的链接)。我认为负面的看起来像这样:(?<!Step Dialog)并导致这个:

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

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

修改
'[Bb]'和': \ s '适用于使用多个冒号和空格(大写“Build”)以不正确格式输入信息的用户。一般来说,清理它的建议值得赞赏,我对正则表达式来说相对较新。

2 个答案:

答案 0 :(得分:2)

你很接近,但它仍然匹配,因为它可以找到满足.*的字符串,而不是Step Dialog。正面和负面断言仅影响紧邻它们的模式。因此,您必须强制它检查您不希望与Step Dialog匹配的每个字符。

试试这个:

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

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

你会注意到我也把它变成了一个积极的前瞻,因为它更容易理解发生了什么。

答案 1 :(得分:0)

你可以通过几种方式做到这一点,但是你很接近。

`.*(?<!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。第二个应该没问题。