2011-10-14 46 views
2

我們解析由自動腳本創建的日誌。我們會關心一個典型的就是字符串:'1.10.07-SNAPSHOT (1.10.07-20110303.024749-7)'從以下線路:Python正則表達式負面lookbehind

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'' 

我的正則表達式這是目前。 '(?!.*<)'是我第一次嘗試避免這個問題,因爲有些用戶會寫''。儘管如此,這並不能解決上述問題。我認爲要做的正確的事情將會是一個負面的後臺,如果'Step Dialog'存在就行了,但我的寫作嘗試似乎失敗了,根據regexr(由於某些原因,它不讓我分享鏈接到我保存的表單)。我以爲負回顧後應該是這樣的:(?<!Step Dialog)並導致此:

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

但是這是由於某種原因,既符合上述的第一和第三行。

編輯:
「[BB]」和「:\ S」是誰通過使用多個冒號和空格不正是正確的格式輸入的信息的用戶,符合資本化「建設」。一般來說,清理這些問題的建議是值得讚賞的,我對正則表達式比較陌生。

回答

2

您已經接近,但它仍然匹配,因爲它可以找到一個字符串,滿足.*,但不會在前面加Step Dialog。正面和負面的斷言隻影響周圍的模式。因此,你必須強制它檢查你不想匹配的每個角色Step Dialog

試試這個:

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

現在,它確保^(行的開頭)和[Bb]uild [Vv]ersion之間的每個字符字符串Step Dialog

你會注意到我也將它改爲了積極的向前看,因爲它更容易理解正在發生的事情。

+1

非常好,非常感謝!我也從中學到了(?:...),這是我以前想知道的功能。 – Nathan

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中工作。但第二個應該沒問題。

+3

這些模式中的第一個將給出編譯錯誤,因爲後視不是固定寬度。 – ekhumoro

+0

@ekhumoro - 好的。我忘記了Python對可變寬度lookbehinds的厭惡。編輯 –

+0

這是爲什麼downvoted?如果仍然不正確,請解釋原因。 –

相關問題