使小正则表达式更具可读性

时间:2010-09-30 18:44:53

标签: regex code-formatting

我有一个正常的表达式,但我想让它更具可读性,而且我远不是一个正则表达式的大师,所以我谦卑地希望得到一些提示。

这是为了抓取几个不同的编译器,链接器和其他构建工具的输出,并用于构建一个漂亮的小夏季报告。它的工作做得很好,但我感觉我是以一种笨重的方式写出来的,而且我很快就学会了,而不是保持错误的方式。

(.*?)\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

我最感兴趣的是让第二和第四个条目更加美丽。出于某种原因,我正在使用的正则表达式测试器(The Regulator)与普通空格不匹配,所以我不得不使用\ s ...但它并不意味着匹配任何其他空格。

任何学校教育都将受到高度赞赏。

3 个答案:

答案 0 :(得分: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
.*$

答案 1 :(得分:2)

第2行

我认为你的正则表达式与评论不符。你可能想要这个:

(\s:\s)?

使其无法捕获:

(?:\s:\s)?

应该能够使用文字空间而不是\s。这必须是您正在使用的工具的限制。

第4行

[0-9][0-9][0-9][0-9]可以替换为[0-9]{4}

在某些语言中[0-9]相当于\d

答案 2 :(得分:0)

也许您可以从子表达式构建RE,以便您的结束RE看起来像这样:

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