`
nanjingjiangbiao_T
  • 浏览: 2739808 次
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

正则表达式的几种引擎

 
阅读更多

正则引擎主要可以分为基本不同的两大类:一种是DFA(确定性有穷自动机,学过计算理论的应该都知道),另一种是NFA(非确定性有穷自动机),DFA和NFA都有很长的历史,NFA的历史更长一些,两者在二十多年的发展中产生了许多不必要的变体。而POSIX标准的出台是为了规范这种现象。POSIX标准不但清楚地规定了引擎应该支持的元字符和特性,还明确规定了使用者期望由表达式获得的准确结果。DFA已经符合新的标准,而NFA则需要修改才能符标准。这样一来,正则引擎可以粗略地分为3类:DFA、传统型NFA、POSIX NFA,表格 1是从书中摘出来的,基本涵盖了现在主流的大部分程序。

表格 1

引擎类型 程序
DFA awk (大多数版本)、egrep(大多数版本)、flex、lex、MySQL、Procmail
传统型NFA GNU Emacs、Java、grep(大多数版本)、less、more、.NET语言、PCRE library、Perl、PHP(所有三套正则库)、Python、Ruby、sed(大多数版本)、vi
POSIX NFA mawk、Mortice Kern Systems’ utilities、GNU Emacs (明确指定时使用)
DFA/NFA 混合 GNU awk、GNU grep/egrep、Tcl

DFA和NFA反映了将正则表达式在应用算法上的根本差异。NFA可以称为表达式主导的引擎,DFA则可以称为文本主导。所谓表达式主导是指在每一个匹配过程中,每一个子表达式都是独立的,或者可以认为一条由多个子表达式组成的正则表达式在表达式主导的引擎中等效于基本等效于多条表达式串行执行(当然公共部分是不会被重复执行的)。而在文本主导的引擎中,多条子表达式会在扫描文本时同时进行匹配。

在书上举了个例子,基本说明了这两种方式的不同:用to(nite|knight|night)匹配文本’tonight’,当表达式主导引擎来匹配时,在匹配完to后会依次匹配nite、knight、night直到匹配成功为止(即匹配night时)。而文本主导的引擎匹配时,会记录当前有效的所有匹配可能,所以当匹配完to时,由于knight的k不能匹配,所以被淘汰出局,这时剩下的是两个有效的可能匹配(nite和night),当扫描到g时就只剩下一个可能匹配了,当h和t完成匹配时,引擎发现匹配完成,报告成功。

以上的匹配过程其实引出了几个概念,同时我们也可以从这个例子中看出两种引擎的不同。在NFA中由于表达式主导的串行匹配方式,所以用到了回溯(backtracking),按照书中的说法,这个是NFA最重要的部分,每一次某个分支的匹配失败都会导致一次回溯,因此如何正确的选择表达式,减少回溯次数就成为了提高NFA引擎下正则表达式工作效率的关键。具体内容可以参考相关资料。另外还有两个DFA中没有的概念:“匹配优先量词”和“忽略优先量词”。(在DFA中只有匹配优先,这个也很好理解,一方面是DFA没有也不需要回溯,另外一个原因是DFA的最左最长原则,在下文会提到)这里也不展开了,网上有不少资料讲这两个概念,以及如何灵活选择两种量词来提高效率的范例。

总的来说DFA和NFA的明显区别之一在于效率,正如上面说到的,由于DFA没有回溯,因此看起来在某些情况下会比NFA来得更快,但是在真正使用中,DFA需要进行预编译才能获得更好效果,因为DFA的匹配方式需要更多的内存和时间,在第一次遇到正则表达式时需要比NFA详细得多的方法来分析这个表达式,不过可以预先把对不同正则表达式的分析结果建好,DFA就可以获得比NFA更优的速度。虽然NFA速度更慢,并且实现复杂,但是它又有着比DFA强大的多的功能,比如支持环视,支持反向引用(虽然这个是非正则的)等。除此之外,最大的区别就在于最左最长规则(longest of the leftmost)这是在POSIX标准中规定的一条原则,即如果在字符串的某个位置存在多个可能的匹配,则返回的是最长的匹配,又由于匹配时总是从左边开始的,所以叫最左最长规则。DFA天然地支持这一条规则,而NFA由于使用了回溯,并且会在匹配时立刻返回结果,再加上忽略优先量词的存在,使得它天然地不支持这条规则……,当然如果对NFA进行一些修改,要求其在首次匹配时不是停下来而是穷尽所有结果,最后返回最长的结果,则NFA就被改造成了POSIX NFA。

正则表达式的终极境界是兼具DFA的速度和NFA的功能,比如GNU grep采取了一种简单有效的策略,在平时尽可能多地使用DFA,在需要用到反向引用的时候,才切换到NFA,可以得到很不错的结果。


分享到:
评论

相关推荐

    深入浅出正则表达式,正则表达式详细介绍

    正则表达式(Regular Expression),简称regex或regexp,是一种用于描述文本模式的强大工具。它可以帮助我们在文本中进行精确匹配、查找以及替换操作。正则表达式的概念最早可以追溯到20世纪50年代,但真正流行起来...

    正则表达式匹配调试工具

    正则表达式是一种强大的文本处理工具,用于在字符串中进行模式匹配和查找、替换等操作。在编程和数据处理领域,正则表达式是不可或缺的一部分,尤其在处理大量文本数据时,它的灵活性和效率尤为突出。为了更好地理解...

    linux 正则表达式总结

    正则表达式的第一个实用应用程序是 Unix 中的 qed 编辑器,从那时起,正则表达式经过几个时期的发展,现在的标准已经被 ISO 批准和被 Open Group 组织认定。 2. 语言?NO! 正则表达式并非一门专用语言,而是一种...

    Javascript正则表达式教程

    下面通过几个例子来具体说明正则表达式的使用方法: 1. **匹配任意字符**:使用`.`可以匹配除换行符外的任意字符。例如,“`.*`”可以匹配任何字符序列。 2. **匹配单词边界**:使用`\b`可以匹配单词的边界。例如,...

    神奇的匹配 正则表达式求精之旅

    正则表达式,简称为正则,是一种强大的文本处理工具,广泛应用于编程语言、文本编辑器和搜索引擎等场景。在“神奇的匹配 正则表达式求精之旅”中,我们将深入探讨这一技术的奥秘,揭示其在数据查找、提取、替换等...

    正则表达式C语言源码

    正则表达式是一种强大的文本处理工具,用于在字符串中匹配特定模式。在计算机科学和编程领域,正则表达式(Regular Expression,简称regex)被广泛应用于数据验证、搜索与替换等任务。C语言,作为一门基础且通用的...

    正则表达式系统教程.RAR

    正则表达式是一种强大的文本处理工具,用于在字符串中进行模式匹配和搜索替换。它在编程、数据分析、文本挖掘等领域有着广泛的应用。本教程旨在帮助你深入理解和熟练掌握正则表达式,通过学习,你可以有效地查找、...

    正则表达式的调试器java实现

    正则表达式是一种强大的文本处理工具,用于匹配、查找、替换和分析字符串模式。在Java中,正则表达式被广泛应用于数据验证、文本搜索和替换等场景。本项目是基于Java实现的一个正则表达式调试器,通过NetBeans集成...

    深入浅出正则表达式(一)

    正则表达式在实际工作中有着广泛的应用,包括但不限于以下几个方面: 1. **数据验证**:通过定义一定的规则,确保输入的数据格式正确。 2. **搜索替换**:在文本文件中快速搜索并替换特定模式的内容。 3. **文本...

    正则表达式30 分钟入门教程

    正则表达式是处理文本和数据的强大工具,尤其在搜索引擎、语言翻译、文本处理和信息抽取等方面有着重要应用。通过对正则表达式的掌握,可以高效地搜索和替换文本,验证数据的格式正确性等。 正则表达式使用一些特定...

    精通正则表达式_第三版(高清版).

    正则表达式,也称为“正则式”,是一种文本模式,包括普通字符(例如,字母和数字)和特殊字符(称为“元字符”)。它使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。正则表达式在编程和文本处理领域...

    最全正则表达式教程、最好正则表达式教程.pdf

    当我们说某个字符串匹配某个正则表达式时,通常是指该字符串的一部分或几部分满足正则表达式定义的模式。 **示例**: 假设我们需要查找所有以`0`开头,随后是2-3个数字,接着是一个连字号“-”,最后是7或8位数字的...

    C#正则表达式测试工具,传统NFA引擎

    正则表达式是一种强大的文本处理工具,用于匹配、查找、替换和分析字符串模式。在C#编程语言中,正则表达式是通过`System.Text.RegularExpressions`命名空间中的类来实现的,其中最为关键的是`Regex`类。这个压缩包...

    正则表达式入门经典(书签版)美.瓦特

    正则表达式是一种强大的文本处理工具,用于在字符串中进行模式匹配和搜索替换操作。它在编程、数据处理和文本分析等领域中广泛应用。《正则表达式入门经典》由美国作家Andrew Watt所著,这本书为初学者提供了全面而...

    正则表达式简明参考.pdf

    正则表达式是一种用于匹配字符串中字符组合的模式。它在各种编程语言、脚本语言以及文本处理工具中广泛使用。以下详细解析了正则表达式中的一些重要知识点: 元字符是正则表达式中具有特殊意义的字符。例如点号(.)...

    给大家分享一个好用的正则表达式工具

    正则表达式是一种强大的文本处理工具,用于在字符串中匹配、查找、替换或者提取特定模式。在编程和数据处理领域,正则表达式是不可或缺的一部分,尤其在处理大量文本数据时,它的效率和灵活性尤为突出。 标题中的...

    正则表达式教程 正则码

    正则表达式是一种强大的文本处理工具,用于在字符串中匹配特定模式。它是计算机科学和编程领域中的一个核心概念,尤其在数据验证、搜索与替换、文本解析等方面有着广泛的应用。正则表达式由一系列特殊字符和普通字符...

    DEELX正则表达式引擎

    正则表达式(Regular Expression,简称regex)是一种模式匹配语言,允许我们用简洁的语法来表示复杂的字符串匹配规则。DEELX引擎优化了这一过程,提供了高效且灵活的解决方案。 DEELX引擎的特性可能包括但不限于...

    一个很小的正则表达式测试软件

    正则表达式(Regular Expression,简称regex)是用于匹配字符串的一种模式,广泛应用于文本处理、数据验证、搜索和替换等场景。在IT行业中,掌握正则表达式是提高工作效率的关键技能之一。微软推出的这款“正则...

    正则表达式入门教程。

    在正则表达式中,有几个关键概念和特殊字符,例如: 1. **元字符**: 元字符是具有特殊含义的字符,如 `\b`、`.`、`^`、`$`、`\d`、`\w` 等。它们不直接代表自己,而是代表某种特定的模式。例如,`\b` 表示单词边界...

Global site tag (gtag.js) - Google Analytics