JS编程建议——46:提高正则表达式执行效率

建议46:提高正则表达式执行效率
(1)关注如何让匹配更快失败
正则表达式处理慢往往是因为匹配失败过程慢,而不是匹配成功过程慢。使用正则表达式匹配一个很大字符串的一小部分,情况更为严重,正则表达式匹配失败的位置比匹配成功的位置要多得多。一个修改使正则表达式匹配更快但失败更慢,例如,通过增加所需的回溯次数尝试所有分支的排列组合,这通常是一个失败的修改。
(2)正则表达式以简单的、必需的字元开始
最理想的情况是,一个正则表达式的起始字元应当尽可能快速地测试并排除明显不匹配的位置。用于此目的好的起始字元通常是一个锚(^或$)、特定字符(如x 或u363A)、字符类(如[a-z]或速记符、单词边界(b))。如果可能,避免以分组或选择字元开头,避免顶级分支,如/one|two/,因为这样会强迫正则表达式识别多种起始字元。
Firefox浏览器对起始字元中使用的任何量词都很敏感,能够优化得更好。例如,以ss*替代s+或s{1,}。其他浏览器大多优化掉这些差异。
(3)编写量词模板,使它们后面的字元互相排斥
当字符与字元相邻或子表达式能够重叠匹配时,一个正则表达式尝试分解文本的路径数量将增加。为避免出现此现象,尽量具体化模板。当表达“1”时不要使用“.?”(依赖回溯)。
(4)减少分支的数量,缩小它们的范围
当分支使用 | (竖线)时,可能要求在字符串的每一个位置上测试所有的分支选项。通常可通过使用字符类和选项组件减少对分支的需求,或者将分支在正则表达式上的位置推后(允许到达分支之前的一些匹配尝试失败)。
字符类比分支更快,因为它们使用位向量实现(或其他快速实现)而不是回溯。当分支必不可少时,在不影响正则表达式匹配的情况下,将常用分支放在最前面。分支选项从左向右依次尝试,一个选项被匹配上的机会越多,它被检测的速度就越快。
注意:由于Chrome 和Firefox 浏览器自动执行这些优化中的某些项目,因此较少受到手工调整的影响。
(5)使用非捕获组
捕获组花费时间和内存用于记录后向引用,并保持它们是最新的。如果不需要一个后向引用,可通过使用非捕获组避免这种开销,例如,(?:…)替代(…)。当需要一个完全匹配的后向引用时,有些人喜欢将正则表达式包装在一个捕获组中,这是不必要的,因为可以通过其他方法引用完全匹配。例如,使用regex.exec()返回数组的第一个元素,或替换字符串中的$&。用非捕获组取代捕获组在Firefox 浏览器中影响很小,但在其他浏览器上处理长字符串时影响很大。
(6)捕获感兴趣的文字,减少后处理
如果要引用匹配的一部分,应当通过一切手段,捕获那些片断,再使用后向引用处理。例如,编写代码处理一个正则表达式所匹配的引号中的字符串内容,使用/"(2)"/之后再使用一次后向引用,而不是使用/"2"/之后从结果中手工剥离引号。当在循环中使用时,减少这方面的工作可以节省大量时间。
(7)暴露所需的字元
为帮助正则表达式引擎在如何优化查询例程时做出明智的决策,应尽量简单地判断出那些必需的字元。当字元应用在子表达式或分支中时,正则表达式引擎很难判断它们是不是必需的,有些引擎并不做此方面的努力。例如,正则表达式/^(ab|cd)/暴露它的字符串起始锚。IE 和Chrome浏览器会注意到这一点,并阻止正则表达式尝试查找字符串头端之后的匹配,从而使查找瞬间完成而不管字符串长度。但是,由于等价正则表达式/(^ab|^cd)/不暴露它的^锚,IE无法应用同样的优化,最终无意义地搜索字符串并在每一个位置上匹配。
(8)使用适当的量词
正如建议45所讨论过的那样,“贪婪”量词和“懒惰”量词即使匹配同样的字符串,其查找匹配过程也是不同的。在确保正确等价的前提下,使用更合适的量词类型(基于预期的回溯次数)可以显著提高性能,尤其在处理长字符串时。
(9)将正则表达式赋给变量,以重用它们
将正则表达式赋给变量以避免对它们重新编译。有人使用正则表达式缓存池,以避免对给定的模板和标记组合进行多次编译。不要过分担心,正则表达式编译得很快。重要的是避免在循环体中重复编译正则表达式。换句话说,不要这样做:
while (/regex1/.test(str1)) {

/regex2/.exec(str2);
...

}
替代做法如下:
var regex1 = /regex1/,
regex2 = /regex2/;
while (regex1.test(str1)) {

regex2.exec(str2);
...

}
(10)将复杂的正则表达式拆分为简单的片断
尽量避免一个正则表达式做太多的工作。处理复杂的搜索问题需要将条件逻辑拆分为两个或多个正则表达式,这样更容易解决问题,通常也更高效,每个正则表达式只在最后的匹配结果中执行查找。在一个模板中完成所有工作的正则表达式很难维护,而且容易引起回溯相关的问题。


  1. "rn
  2. "
时间: 2024-09-29 04:24:09

JS编程建议——46:提高正则表达式执行效率的相关文章

SQL教程:提高SQL执行效率的几点建议

提高SQL执行效率的几点建议: ◆尽量不要在where中包含子查询; 关于时间的查询,尽量不要写成:where to_char(dif_date,'yyyy-mm-dd')=to_char('2007-07-01','yyyy-mm-dd'); ◆在过滤条件中,可以过滤掉最大数量记录的条件必须放在where子句的末尾; FROM子句中写在最后的表(基础表,driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.如果有三个以上的连接查询,

提高SQL执行效率的几点建议

提高SQL执行效率的几点建议: 尽量不要在where中包含子查询; 关于时间的查询,尽量不要写成:where to_char(dif_date,'yyyy-mm-dd')=to_char('2007-07-01','yyyy-mm-dd'); 在过滤条件中,可以过滤掉最大数量记录的条件必须放在where子句的末尾; FROM子句中写在最后的表(基础表,driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.如果有三个以上的连接查询,那就

分享50个提高PHP执行效率的技巧_php实例

1.用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量, 单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的"函数"(译注:PHP手册中说echo是语言结构,不是真正的函数,故 把函数加上了双引号). 2.如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍. 3.$row['id'] 的速度是$row[id]的7倍. 4.echo 比 print 快,并且使用echo的多重参数(译注:

对提高ASP执行效率的几点看法

执行 对提高ASP执行效率的几点看法:<br><br>1.硬件问题:<br>服务器的设置和配置无疑是ASP执行速度的最主要决定因素,但有关这方面的问题与MiMi有关,无需罗嗦.<br><br>2.避免在一个页面中是用多种脚本语言<br>如:<script language="vbs">和<script language="javascript"><br>因为如

Oracle提高sql执行效率的心得建议

sql执行效率一直都是为人所关注,那到底应该怎样提高呢?有什么比较好的方法,下面与大家分享下比较不错的建议,感兴趣的朋友可以参考下,希望对大家有所帮助 复制代码 代码如下: -->FROM子句中包含多个表的情况下,选择记录条数最少的表作为基础表 -->解析WHERE子句是自下而上的 过滤条件要有顺序 -->ORACLE会将'*'转换成列名 -->DELETE会在rollback segment中存放可恢复信息,可以试试TRUNCATE -->COMMIT会释放:1.rollb

JS编程建议——38:正确认识正则表达式工作机制

建议38:正确认识正则表达式工作机制有很多因素影响正则表达式的效率.首先,正则表达式适配的文本千差万别,部分匹配时比完全不匹配所用的时间要长.其次,每种浏览器的正则表达式引擎也有不同的内部优化.要有效使用正则表达式,重要的是理解它们的工作机制.一个正则表达式处理的基本步骤如下:第1步,编译.在创建了一个正则表达式对象后,浏览器先要检查模板有没有错误,然后将它转换成一个本机代码例程,用于执行匹配工作.如果将正则表达式赋给一个变量,就可以避免重复执行此步骤.第2步,设置起始位置.当一个正则表达式投入

JS编程建议——41:正确使用正则表达式引用

建议41:正确使用正则表达式引用正则表达式在执行匹配运算时会自动把每个分组(子表达式)匹配的文本都存储在一个特殊的地方以备将来使用.这些存储在分组中的特殊值被称为反向引用.反向引用将遵循从左到右的顺序,根据表达式中左括号字符的顺序进行创建和编号.var s = "abcdefghijklmn";var r = /(a(b(c)))/;var a = s.match(r); //["abc", "abc" , "bc" , &q

有效提高JavaScript执行效率的几点知识_javascript技巧

为了提供新鲜.别致的用户体验,很多网站都会使用 JavaScript 来改善设计.验证表单.检查浏览器,以及Ajax请求,cookie操作等等,实现无刷新动态效果 .但是,要将大量内容在浏览器呈现,如果处理不好,网站性能将会急剧下降.所以我们有必要了解下,如何提高JavaScript的执行效率. JavaScript 函数 在JavaScript 中,函数在使用前会预编译.尽管有些时候下可以使用字符串代替函数,但是每次执行这段JavaScript 代码时都会重新解析,影响性能. 1.eval例子

JS编程建议——25:恰当选用if和switch

建议25:恰当选用if和switchswitch结构中存在很多限制,存在这些限制的主要目的是提高多重分支结构的执行效率.因此,如果能够使用switch结构,就不要选择if结构.无论是使用if结构,还是使用switch结构,应该确保下面3个目标的基本实现:准确表现事物内在的.固有的逻辑关系.不能为了结构而破坏事物的逻辑关系.优化逻辑的执行效率.执行效率是程序设计的重要目标,不能为了省事而随意耗费资源.简化代码的结构层次,使代码更方便阅读.相对来说,下面几种情况更适合使用switch结构:枚举表达式