2010-09-30 11 views
3

我有一個工作正則表達式,但我想使它更有點可讀性,而且我遠離正則表達式大師,所以我很謙虛地希望一些技巧。使一個小的正則表達式更易讀

這是設計用來刮取幾種不同的編譯器,鏈接器和其他編譯工具的輸出,並用於構建一個不錯的小報告。它的工作很好,但我感覺就像我以笨重的方式寫下它,而且我很快就會學習,而不是保持錯誤的方式。

(.*?)\s?:?\s?(informational|warning|error|fatal error)?\s([A-Z]+[0-9][0-9][0-9][0-9]):\s(.*)$ 

其中,簡單細分,如下:

(.*?)          # non-greedily match up until... 
\s?:?\s?         # we come across a possible " : " 
(informational|warning|error|fatal error)? # possibly followed by one of these 
\s([A-Z]+[0-9][0-9][0-9][0-9]):\s   # but 100% followed by this alphanum 
(.*)$          # and then capture the rest 

我在做第2個及以上更多...美麗的4項最感興趣。出於某種原因,我使用的正則表達式測試器(The Regulator)與空格不匹配,所以我必須使用\ s ...但它並不意味着要匹配任何其他空格。

任何學校將不勝感激。

+2

你能「美麗」和「正則表達式」在同一個句子中使用? – 2010-09-30 18:47:31

+2

你使用哪種編程語言的正則表達式? – 2010-09-30 18:54:14

回答

2

線2

我覺得你的正則表達式不匹配的評論。你可能想這個:

(\s:\s)? 

使其成爲非捕獲:

(?:\s:\s)? 

應該能夠使用文字空間,而不是\s。這必須是您使用的工具的限制。

[0-9][0-9][0-9][0-9]線可以與[0-9]{4}代替。

在某些語言中[0-9]相當於\d

+0

我喜歡旁邊的非捕獲位......有沒有可能要求這兩個可選組中的一個?即一個或另一個或兩者,但不是兩者都不? – Nate 2010-09-30 19:05:32

+0

@Nate:我認爲這是最好的方法:'((informational | warning | error | fatal error)(\ s:\ s)?| \ s:\ s)' – 2010-09-30 19:08:57

4

做出長期的正則表達式更可讀的最簡單的方法是使用「free-spacing」(或\xmodifier,這將讓你寫,就像你在代碼的第二塊做你的正則表達式 - 它使忽略空白。但是,這並不是所有引擎都支持的(根據上面鏈接的頁面,.NET,Java,Perl,PCRE,Python,Ruby和XPath都支持它)。

還要注意的是,在自由空間模式,你可以使用[ ]而不是\s如果你想只匹配空格字符(除非你使用的是Java,在這種情況下,你必須使用,這是一個逃脫空間)。

有算不上什麼可以爲第二行做的,如果你想每一個元素是可選的獨立於其他元素,但第四可縮短:

\s([A-Z]+\d{4}):\s 

\dshorthand class相當於[0-9]{4}指定它應該出現exactly four times

第三行可以稍微縮短以及((?:…)指定非捕獲group):

(informational|warning|(?:fatal)? error)? 

從效率的角度來看,除非你確實需要每次使用括號時間捕獲的子模式,你可以刪除所有這些,除了第三行,alternation需要這個組),但是那個可以不被捕獲。把所有這些組合起來,你會得到:

.*? 
\s?:?\s? 
(?:informational|warning|(?:fatal)?error)? 
\s[A-Z]+\d{4}:\s 
.*$ 
+0

我與\ x ...合作,儘管我沒有在這裏使用它(剛剛發現了關於\ x哦......昨天:)。我更感興趣的是,如果實際上有比我用於第2行和第4行更好的正則表達式語法, – Nate 2010-09-30 18:50:56

0

也許你可以建立從子表達式的RE,讓您的最終RE會是這個樣子:

/$preamble$possible_colon$keyword$alphanum$trailer/