正则表达式优化

来源:互联网 发布:通达信布林线指标源码 编辑:程序博客网 时间:2024/06/04 23:25

正则表达式的优化  在Jeffrey E. F. Friedl 的<<精通正则表达式>>中提到了几种技巧。今天着重说一种比较实用的。

 

比较简单的:

        在类似 .* 或者 [\s\S]*中匹配的时候,量词* 默认是贪婪的,启用最大匹配模式, 会匹配到尽量多的字符串,如果我们的需求是匹配<b>text</b>中的text,这样就不适用了。具体来说,我们假设这个正则表达式是: <b>.*</b>但是如果目标字符串很长 <b>text</b>ssssssssssss....(此处省略100000个s) 这样就很悲催,.* 会匹配<b>后面所有的字符串,也就是 100000+ 的字符串,然后一个一个回朔,回朔100000多次之后才正确匹配</b>

       很显然这种量词最大匹配的模式效率很差,当然字符串小的话无所谓,可以用?号开启最小匹配模式。优化后的表达式是 <b>.*?</b> , 让*号默认从小的开始,就是匹配一个字符之后,将后面的跟</b>进行对比。这样4次比较就哦了。 

 

稍微复杂点的:

在书中,提炼出了一种匹配的通用模式

normal*(specail normal*) 咋一看不知道什么意思,简单的说 就是让normail尽量多的匹配正常的文本,然后摘出需要特殊处理的字符,增加对非常规字符的处理。我们举一个例子来说明这种问题。

还是匹配<b>text</b> 一般的,严格一点,我们使用 <b>(?!</?b>.)*</b>来匹配只要中间不出现<b>或者</b>都认为结束了,但是这是一个串匹配的过程,效率还不是最优的。

用通用模式来实现可以写成:

<b>                       #匹配开头的<b>

    (?>[^<]*)            #匹配任意数量的normal 

       (?>                 #固化分组

           (?!</?b>)    #锚定不是需要标签的字符

           <                  #特殊字符

           [^<]*              #匹配任意数量的normal

        )*                      #

</b>                          #匹配尾部的</b>

这种模式的核心思想视永不回朔,永远向前匹配,技巧性很强,你得先分析出什么字符可以作为specail的,在本例中,使用了< 字符,应为</b>的第一个字符就是 < , 把中间的内容都跟<比, 中间内容可能含有<a><html>诸如此类的内容, 要把<a>跟</b>区分开来,使用了锚定,相当于在有< 的时候做下判断,是单字符比较,速度较快。

0 0