正则表达式重复子模式前、后倾的性能比较

在准备内部的正则表达式 (Regular Expression)分享的过程中, 注意到一个细节问题:重复的子模式,是应该前倾还是后倾,这两者在性能上有什么差异?

前倾和后倾是我胡诌的两个词,我的定义如下:

前倾 就是前面的子表达式使用贪婪匹配或较大的量词,尽可能多的匹配内容, 导致前面匹配的内容较多而使“天平”前倾。例如:/(?:\d{1,3}\.){3}\d{1,3}/
后倾 则相反,后面的子表达式使用贪婪匹配或较大的量词。如:/\d{1,3}(?:\.\d{1,3}){3}/

前倾和后倾在实际应用中很常见,如时间,主机名等,中间以某特殊字符(串?)分隔, 被分隔部分的规则又相同的情况下,一般都是使用这两种实现方式之一。

上面定义中的两个例子只是简例,可以用来大致匹配 IPv4 地址,完整的 IPv4 地址正则式如下, 它要求每段都在 0-255 之间: 前倾:

/^(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/
1

后倾:

/^(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}$/
1

我写了一个测试比较这两个正则性能 的页面,在 IE7, FF3.6, Safari 4, Opera 10 下测试均为前倾的性能较高,Chrome 4 下则不相伯仲。

p.s. 这种重复子模式,要有语法上的简写就好了,像 Perl 正则的递归引用(或类似运行时反向引用), 维护起来就方便多了。

Help
[count]gg 跳转到第 [count] 行,默认第 1 行。
[count]G 跳转到第 [count] 行,默认最后一行。
[count]j 向下跳转 [count] 行,默认跳转一行。
[count]k 向上跳转 [count] 行,默认跳转一行。
/ 开始搜索。按 <Esc> 退出。
gh 跳转到首页。
gb 跳转到博客首页。
gw 跳转到 Wiki 首页。
gt 跳转到我的 Twitter Profile 页。
gp 跳转到我的 Github Profile 页。
? 打开帮助。按 <Esc> 退出。