`

正则表达式是如何工作的? 正则表达式性能

 
阅读更多

转自:http://www.nowamagic.net/librarys/veda/detail/2026

正则表达式 ,是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。在很多文本编辑器或其他工具里,正则表达式通常被用来检索和/或替换那些符合某个模式的文本内容。

粗浅地编写正则表达式是造成性能瓶颈的主要原因之一,但还有很多可以改进正则表达式效率的地方。两个正则表达式匹配相同的文本并不意味着他们具有同等的速度。

许多因素影响正则表达式的效率,首先,正则表达式适配的文本千差万别,部分匹配时比完全不匹配所用的时间要长。每种浏览器的正则表达式引擎也有不同的内部优化。

正则表达式的核心是正则表达式引擎处理方式。一般正则表达式引擎分为两种:NFA和DFA。但其中的NFA又有两个分支:传统的NFA和POSIX NFA 以下是各种语言所支持的引擎:

  • 传统NFA:GNU Emacs、java、grep、less、more、.NET、Perl、PHP、Python、Ruby、sed等
  • DFA:awk、egrep、flex、MySQL、Procmail
  • POSIX NFA:mawk、Mortice Kern等等。
  • DFA/NFA混合引擎:GNU awk 、GNU grep/egrep、Tcl

正则表达式真正起作用是由于这些引擎来计算匹配。所以要想弄懂正则表达式的内部机制,就必须要明白你所熟悉的语言(如java,.net用的都是传统的NFA)是采用的那种引擎。每一种语言都有这自己引擎,也就有自己的独特的规范和独特的匹配原则。所以正则表达式说采用的匹配结果也不一样。但不管是DFA还是NFA他们又有一些共性原则如:

  1. 优先匹配最左端(最靠开头)的匹配结果。
  2. 标准的匹配量词(*、+、?和{min,max})是匹配优先的。

最左端匹配结果

如果你用:cat来匹配下面的一句话:The dragging belly indicates that your cat is too fat.

你本想匹配其中的cat,但是结果却不是,而是indicates中的cat。单词cat 是能够被匹配出来,但是indicates中的cat出现 的更早,所以就先匹配成功了。对于java程序员来说,他只关心是否能匹配而不关心在哪匹配。再来一个例子: 用:fat | cat | belly | your来匹配字符串上面的那一句话。结果会是什么呢?

你认为会是最后的fat是吗?因为fat在 fat | cat | belly | your最前面,是吗?错:答案是belly,句中的belly,为什么呢?由于匹配是从句中的第一个字母T来一次匹配fat | cat | belly | your,中的所有选项,结果发现都不符合,就走到h来匹配,结果也不符合,就依次走下去,直到b字母,有一项符合,就是fat | cat | belly | your中的belly中的b,所以依次匹配发现成功了,所以就正确了。就不在向后面的单词匹配(这种结果只是在支持NFA的引擎中)。

标准量词(*、+等)是匹配优先(greedy 贪婪的意思)的

用\b\w+s\b 来匹配包含s的字符串,如regexes,整个是能够比配成功的,你或许会认为它是正则表达式\w+匹配到xe结束然后让s来匹配最后的regexes中的s,若你这样想,那就错了,其实\w+一次性的匹配到结束包括s在内都被它给匹配了,但后面有个s所以,她很不情愿的吐出一个s来,让后面的s来匹配。这样使得匹配成功。这个+是不是很greedy啊?像欧也妮~葛朗台是吗?O(∩_∩)O哈哈~,对了,就是,这条规则很重要,对于正则表达式的优化很重要。很多时候就是在这个基础上进行优化的。

下面就再来比较一下DFA和NFA的区别。

一般DFA速度较快,而NFA的控制能力较强。这两者各有千秋。NFA引擎是表达式主导。

为了有效地使用正则表达式,重要的是理解它们的工作原理。下面是一个正则表达式处理的基本步骤:

第一步:编译

当你创建了一个正则表达式对象之后(使用一个正则表达式直接量或者RegExp构造器),浏览器检查你的模板有没有错误,然后将它转换成一个本机代码例程,用于执行匹配工作。如果你将正则表达式赋给一个变量,你可以避免重复执行此步骤。

第二步:设置起始位置

当一个正则表达式投入使用时,首先要确定目标字符串中开始搜索的位置。它是字符串的起始位置,或由正则表达式的lastIndex属性指定,但是当它从第四步返回到这里的时候(因为尝试匹配失败),此位置将位于最后一次尝试起始位置推后一个字符的位置上。

浏览器优化正则表达式引擎的办法是,在这一阶段中通过早期预测跳过一些不必要的工作。例如,如果一个正则表达式以^开头,IE 和Chrome通常判断在字符串起始位置上是否能够匹配,然后可避免愚蠢地搜索后续位置。另一个例子是匹配第三个字母是x的字符串,一个聪明的办法是先找到x,然后再将起始位置回溯两个字符。

第三步:匹配每个正则表达式的字元

正则表达式一旦找好起始位置,它将一个一个地扫描目标文本和正则表达式模板。当一个特定字元匹配失败时,正则表达式将试图回溯到扫描之前的位置上,然后进入正则表达式其他可能的路径上。

第四步:匹配成功或失败

如果在字符串的当前位置上发现一个完全匹配,那么正则表达式宣布成功。如果正则表达式的所有可能路径都尝试过了,但是没有成功地匹配,那么正则表达式引擎回到第二步,从字符串的下一个字符重新尝试。只有字符串中的每个字符(以及最后一个字符后面的位置)都经历了这样的过程之后,还没有成功匹配,那么正则表达式就宣布彻底失败。

牢记这一过程将有助于您明智地判别那些影响正则表达式性能问题的类型。

分享到:
评论

相关推荐

    vb正则表达式实例(正则表达式测试程序)

    这个“vb正则表达式实例”很可能是为了帮助开发者测试和理解正则表达式的工作原理而设计的一个应用程序。下面将详细探讨正则表达式的基本概念、在VB.NET中的应用以及如何使用它们进行文本匹配。 1. 正则表达式基础 ...

    正则表达式(Deelx版)|正则表达式(Deelx版)支持库

    Deelx版是专门为提高正则表达式性能和功能而设计的一个支持库,适用于各种编程语言和应用场景。 1. **正则表达式基本概念** - **模式匹配**:正则表达式的核心在于模式,它是由特殊字符和普通字符组成的字符串,...

    C语言正则表达式库

    C语言正则表达式库是用于在C编程环境中处理和匹配正则表达式的软件库。这个库名为PCRE(Perl Compatible Regular Expressions),正如其名,它与Perl语言中的正则表达式语法高度兼容,提供了丰富的功能和强大的匹配...

    java正则表达式.zip

    虽然正则表达式功能强大,但过度使用或者设计复杂的正则可能会导致性能下降。在处理大量数据时,应谨慎使用,并考虑优化匹配策略。 通过这些知识点,开发者可以熟练地在Java程序中运用正则表达式进行各种文本处理...

    正则表达式在数据库查询中的应用

    - **性能考量**:某些数据库系统中,使用正则表达式可能会导致性能下降,特别是在大型数据集上。因此,在设计查询时应考虑性能影响。 - **兼容性问题**:不同的数据库系统支持的正则表达式语法可能存在差异,需要...

    易语言正则表达式文本替换

    总的来说,易语言的正则表达式文本替换功能提供了强大的文本处理能力,对于需要处理和分析文本的程序开发者来说,掌握这项技能能极大地提高工作效率。通过深入理解正则表达式和易语言的相关函数,开发者可以灵活地...

    Lucene 使用正则表达式

    ### Lucene 使用正则表达式 #### 知识点概览 1. **Lucene简介** 2. **正则表达式(regex)在Lucene中的应用** 3. **regexQuery详解** 4. **示例代码解析** 5. **索引创建与查询流程** 6. **正则表达式的语法** #### ...

    正则表达式调试工具

    通过正则表达式调试工具,开发者可以有效地调试和优化正则表达式,避免潜在的性能问题和错误匹配。同时,内置的经典例程有助于新手快速熟悉正则表达式的各种用法,提升开发效率。 在实际应用中,正则表达式常用于...

    正则表达式转NFA实现

    NFA的优势在于它允许并行匹配,即使在面对复杂正则表达式时,其性能也往往优于确定性有限自动机(DFA)。然而,NFA在某些情况下可能会进行不必要的状态转换,导致效率较低。尽管如此,通过ε-转换(即从一个状态无...

    正则表达式学习资料以及练习项目代码很多

    - **正则表达式性能优化**:避免过度复杂的正则表达式,合理使用非贪婪匹配,减少回溯。 - **正则表达式调试**:使用`re.DEBUG`标志编译正则表达式,查看其内部结构。 - **正则表达式在其他语言中的差异**:虽然...

    第11.25节 Python正则表达式编译re.compile及正则对象使用.rar

    1. **性能提升**:编译后的正则表达式对象可以多次重复使用,避免了每次都解析字符串的过程,提高运行速度。 2. **代码清晰**:将正则表达式模式与执行操作分开,使代码更易读、更易于维护。 3. **预处理错误检查**...

    易语言正则表达式匹配中文

    在易语言中,正则表达式是进行文本处理、数据提取和搜索的关键工具,尤其在处理中文字符时显得尤为重要。本文将深入探讨易语言中的正则表达式匹配中文的原理、方法以及应用。 正则表达式(Regular Expression)是一...

    qt正则表达式测试工具

    - 检查正则表达式的性能,避免过度复杂的模式导致效率降低。 在实际开发中,熟练掌握Qt的QRegExp类和正则表达式语法,能大大提高处理文本数据的能力,对于编写高效且健壮的代码至关重要。这个测试工具是提升正则...

    源码(精通正则表达式&实战正则表达式)

    在IT领域,正则表达式(Regular Expression,简称regex)是一种强大的文本处理工具,用于匹配、查找、替换或提取字符串中的特定模式...无论是前端开发、后端开发还是数据处理,精通正则表达式都将极大地提高工作效率。

    使用正则表达式拆分字符串

    - 在某些情况下,正则表达式可能过于复杂,导致性能下降,应谨慎设计正则模式。 通过学习和熟练掌握正则表达式拆分字符串的技巧,开发者可以更好地处理各种文本数据,提高代码的可读性和效率。在实际项目中,结合...

    正则表达式综合练习

    11. **优化技巧**:正则表达式可能会带来性能问题,因此在编写复杂的模式时,应考虑使用非贪婪匹配(`*?`、`+?`、`??`),避免回溯,以及使用预编译模式提高效率。 12. **调试与测试**:使用在线工具(如Regex101、...

    delphi xe 10 正则表达式

    - 在使用正则表达式时,应确保其效率,避免过于复杂的表达式导致性能问题。 通过掌握这些知识,开发者可以在Delphi XE10项目中充分利用正则表达式,提高代码的灵活性和处理文本的能力。无论是数据验证、文本处理...

    正则式工具(自动生成正则表达式)

    - **性能优化**:对正则表达式进行性能分析,帮助用户找到最高效的匹配方式。 - **案例库**:内置大量预设的正则表达式实例,用户可以直接应用或作为参考。 掌握正则表达式是提升编程技能的重要一步,利用"正则式...

    ORACLE.PLSQL正则表达式概述

    然而,正如任何强大工具一样,合理使用正则表达式,考虑其对系统性能的影响,是每个数据库开发者和管理员必须掌握的技能之一。通过理解和熟练掌握ORACLE.PLSQL中的正则表达式,可以显著提高数据处理的效率和准确性,...

    正则表达式.txt,正则表达式.txt

    3. **性能问题**:复杂的正则表达式可能导致性能问题,特别是在处理大量文本时。 通过以上介绍,我们可以看出正则表达式不仅功能强大而且应用场景广泛。掌握好正则表达式对于提升编程效率和解决实际问题有着重要的...

Global site tag (gtag.js) - Google Analytics