2013-11-24 65 views
1

我試圖編寫一個正則表達式來將歷史文件中的文本塊從我正在構建的項目中保存下來。目前我打算在我的文本編輯器(無論是textmate還是sublimetext 2)中手動執行此提取操作,但最終我會使用python或php(尚未決定)將其構建爲腳本化過程。正則表達式Lookbehind問題

都在我的歷史文件的歷史記錄條目的格式爲:

YYYY-MM-DD - Chris -- Version: X.X.X 
==================================== 
- Lorem ipsum dolor sit amet, vim id libris epicuri 
- Et eos veri quodsi appetere, an qui saepe malorum eloquentiam. 
... 

-- 

其中x是在工作下完成的版本號。

我試圖從版本號拉到最後的雙破折號分隔符,它表示文本塊的結尾。

我開始通過創建正則表達式語句來選擇節標題,其工作原理:

(^[\d]{4}-[\d]{2}-[\d]{2}\s-\s[\w]+\s--\sVersion:\s)[\d\.]+$ 

但是,當我試圖把我的括號內的模式進入的外觀背後失敗:

(?<=^[\d]{4}-[\d]{2}-[\d]{2}\s-\s[\w]+\s--\sVersion:\s)[\d\.]+$ 

我一直在環顧四周,迄今爲止,它看起來像這個lookbehind格式是正確的。我似乎無法弄清楚我錯過了什麼。有任何想法嗎?

+0

Lookbehind的幾乎從來沒有這樣用過。 – sln

+0

嘿,我猜這是其中一種罕見的情況;) –

+0

我說的幾乎從來沒有,因爲你可以簡單地捕捉你想要的東西而不排除任何東西,所以你不用它來強制一個條件。您正在使用它從不需要的匹配(組0)中排除。 – sln

回答

1

PHP和Python都不允許任意長度的後視。因此,只要你有一個像+這樣的量詞就不用了。

因此,你的第一次嘗試是唯一能夠在這裏工作的東西。

+0

太棒了!知道我不能做一個可變長度的後臺我把我的標題格式更改爲'YYYY-MM-DD - 版本:XXX - 克里斯'和我的聲明到'(?<=^[\ d] {4} - [\ d] {2} - [\ d] {2} \ S- \ sVersion:\ S)([\ d \] + \ S- \ S [\ W] +)$'。這樣我的所有背後的數據是固定的寬度。這實際上給瞭解析我(或其他開發人員)名字的額外好處,以便使用它。謝謝您的幫助! –

2

由於Joey聲明,在php或python中沒有任何長度的lookbehind。但是PHP有一個解決方法! \K轉義序列。

docs

轉義序列\ķ導致任何先前匹配的字符不 被包括在最後的匹配序列英寸例如,模式:

foo\Kbar 

匹配「foobar」,但報告它已匹配「bar」。該特徵 與後向斷言類似(如下所述)。但是,在這種情況下,真正匹配之前的主體部分不必具有固定長度,因爲後向斷言具有固定長度。

去除一些多餘的括號[]後,你的表情看起來像

(?m)^\d{4}-\d{2}-\d{2}\s-\s\w+\s--\sVersion:\s\K[\d.]+$ 

Online demo

注:

  • (?m):是直列regex modifier
  • 你不需要逃脫點.在字符類:[.]將匹配一個點,而不是任何字符
  • 您可以添加一些量詞的空白字符:\s*\s+
  • \w+還將比賽強調_,所以排除它,你可以使用[^\W_]+
  • 正則表達式真棒
+0

太棒了!感謝您添加註釋和修改後的語句。對於正則表達式我仍然很陌生(上週我開始討論它),所以很高興看到冗餘可以省略,並提示注意。也感謝鏈接到regex101.com。我不知道這個網站存在。這將是一個巨大的幫助。 –

+0

@ChrisSchmitz加入[正則表達式聊天室](http://chat.stackoverflow.com/rooms/25767)瞭解更多提示和技巧,甚至可能會討論您的正則表達式問題 – HamZa

+0

不錯,謝謝另一個有用的鏈接。我需要花一些時間探索一下stackoverflow。我甚至沒有意識到有聊天室:P –