前两天一直心里不好,没有把这个主题写完,现在接着来补上:
一、上篇中说到NFA正则引擎的表达式主导:
(1). 为什么说NFA是表达式主导,请看下面的例子:
用 to(nite | knight | night) 来匹配 " I am going to seeing film tonight,could you go with me? "这段文本。
NFA引擎会从文本中的第一个字母I开始匹配,它会把匹配表达式全部走一遍,然后发现没有成功,则正则表达式引擎会驱动向下走,到达第二个字符-空格,发现整个匹配表达式也没有匹配成功,则继续,然后到a,依次类推,直到“tonight"这个to,成功匹配后,转向文本中tonight中的n,发现(nite)符合,这它不会再向下匹配,返回成功,然后转向tonight中的i,发现也能成功,则它也不会继续向下匹配,然后转向文本tonight中的g,到正则表达式中的(nite)发现t不匹配,则此时正则引擎会回退从knight单词的k字母进行匹配,发现也不符合,则回退,再从night单词中的n开始匹配,发现符合,则继续匹配,然后到i,发现匹配再到g,依次类推直到匹配成功。最后返回匹配成功。
你明白没?其实表达式的控制权在不同的元素字母之间转换,所以我们称之为“表达式主导”
(2). DFA引擎的文本主导:
继续我们的这个例子。
但我们进行I字母的匹配时不成功,就不说了,一直到tonight单词是,前面的to比配成功后,当进行to(nite | knight | night)中的n进行匹配时,DFA会同时向三个选项发出匹配请求,有(nite和night)两个符合,(发现没是同时发出请求)则就会抛弃knight选项,以后就不会再进行匹配,然后是i字母的匹配,发现nite和night都符合,则继续,到tonight中的g,在DFA中同时再向nite和night发出匹配请求,发现只有night符合,就会抛弃nite这个选项,然后继续向下匹配。知道成功。发现没,这种方法少了NFA中的很多的回退,所以效率高。。。。
二、有现在主流的语言都是用的是NFA正则引擎,那我们就来重点介绍它的实现机制:
要想了解其中的原理,我们先了解几个概念:回溯、备用状态
专业术语是回溯其实在我的理解就是回退。NFA引擎最很重要的性质是:她会一次处理各个表达式,或组成元素,遇到需要在两个可能成功中进行选择的时候,她会选择其一,同时记住另一个,以备稍后的可能的需要。
并且重要的是:不论选择那一种途径,如果它能匹配成功,而且正则表达式的余下部分也能匹配成功,此时才宣告最终匹配成功,或许你觉得我这个说的是废话。但你请看下面的,如果正则表达式中余下的部分最终匹配失败,引擎会知道需要回溯到之前作出选择的地方,选择其他的备用分支继续尝试。这样最终表达式所有的可能途径知道最终的成功或失败。回溯常和备用状态联系起来分析,那就来说一下,什么叫备用状态。
按我的理解是:大家应该都知道迷宫,走迷宫最常用的方法就是做记号,此刻我们假如用石头做记号,每当我们遇到十字路口是,我们就丢下一块石头,来标记我们所选择的路口,但我们发现不此路不通时,我们就进行回溯,回退到离我们最近的哪一个十字路口,然后重新选择我们的方向,这种方法是我们最常用的。我要说的是,正则表达式中的备用状态就是那个我们在每个十字路口的石头。其实我觉得这就算递归中的回溯,要是你理解了递归,这个应该不难理解。NFA中的LIFO(后进先出)的原则我觉就是那个迷宫此路不通的记号石头就是我们最好的LIFO例子。
整个NFA中的优化其实就是这个回溯原则和greedy原则(上一篇中讲到的),进行合理的优化和匹配。
三、忽略优先量词(*?、+?、??、{min、max}?、)
针对NFA的greedy原则,正则表达式有了忽略优先量词,这很大程度上解决了,很多由于greedy原则带来的麻烦和效率的问题。她只会匹配符合要求的最小的选择。如:
若用 <B>.*</B> 来匹配<B>I</B>and<B>you</B>are chinese,we are very happy to be chinese.
结果会是:<B>I</B>and<B>you</B>
但用<B>.*?</B>匹配 则结果是:<B>I</B>
四:固化分组:(?>)
使用固化分组,这会让引擎不记住备用状态,这又是能很好的提高正则表达式的效率。这也是优化正则表达式的常用方式。如下面的例子:
用 i.*! 来匹配 iHello! 在没有用固化分组时,是可以匹配成功的。
若用固化分组,i(?>.*)! 来匹配 iHello! 则匹配不成功,由于*是贪婪的她会一直匹配到最后,又由于固化分组了.*,她不会再吐出字符让后面的!来匹配。所以匹配失败。
分享到:
相关推荐
源码学习有助于深入理解正则表达式在PB环境下的工作原理,也可能为自定义或扩展组件功能提供可能。 总的来说,pbregexp组件为PowerBuilder开发者提供了一种强大而灵活的工具,帮助他们更高效地处理文本数据。通过...
`正则表达式系统教程.CHM`这个文件很可能是一份详细的教程,包含了丰富的实例和练习,帮助你深入理解正则表达式的各种用法,从基础到高级,从理论到实践。通过学习,你将能够熟练运用正则表达式解决各种文本处理问题...
- **正则表达式在其他语言中的差异**:虽然正则表达式原理相似,但不同编程语言中的实现可能存在细微差别。 7. **学习资源** - **文档**:Python官方文档中的`re`模块介绍,以及其他专门的正则表达式教程。 - **...
理解并熟练运用这些正则表达式原理和技巧,可以帮助开发者编写出更高效、准确的正则表达式,从而更好地处理和操作文本数据。通过深入学习正则表达式,不仅可以提高工作效率,还能提升编程能力,是每个程序员不可或缺...
本文将深入探讨易语言中的正则表达式匹配中文的原理、方法以及应用。 正则表达式(Regular Expression)是一种模式匹配的语言,用于描述一种字符串的集合。在易语言中,我们可以通过内置的字符串函数来实现正则...
对于初学者,书中会引导他们理解正则表达式的构造和工作原理,逐步建立起对模式匹配的直觉。而对于经验丰富的开发者,它提供了一套全面的参考,帮助解决复杂的问题,提升在实际项目中的应用能力。 正则表达式不仅...
在本教程中,我们将深入探讨如何使用正则表达式来拆分字符串,这对于数据处理和文本分析尤其有用。下面将详细阐述正则表达式的概念、语法以及如何在不同编程语言中实现字符串的拆分。 1. 正则表达式基础 - **模式...
深入浅出之正则表达式(二)是正则表达式系列教程的第二部分,旨在帮助初学者理解和掌握正则表达式的高级概念。本篇主要介绍了以下几个知识点: 1. **单词边界元字符**:`\b` 是一种特殊元字符,用于匹配单词的边界...
十年三版,再显王者风范,近30年开发经验的智慧结晶,深入理解正则表达式,彻底修炼基本功,全球第一本全面深入讲解正则表达式的经典巨著,《程序员》杂志技术主编孟岩鼎力推荐。 专家点评:《精通正则表达式》是...
在深入学习正则表达式之前,我们需要了解其基本概念和工作原理。 1. **什么是正则表达式** 正则表达式(Regular Expression,简称Regex)是一种模式匹配语言,用于描述一组文本字符串的特征。例如,"cat" 这个正则...
《deelx正则表达式测试工具:深入解析与应用》 正则表达式,作为字符串处理中的...通过熟练掌握这款工具,不仅可以提高正则表达式编写和调试的速度,还能加深对正则表达式原理的理解,从而在实际开发工作中游刃有余。
你可以根据自己的需求定制工具,或者研究其内部实现以深入理解正则表达式的工作原理。 在使用正则表达式实时测试工具时,开发者可以遵循以下步骤: 1. 理解正则表达式的基础概念,如字符类(如\d表示数字,\w表示...
《精通正则表达式(第3版)》,以明晰轻松的笔调向程序员深入浅出地讲解复杂的知识,并给出了现实世界中复杂问题的解决办法,读者能够立刻运用书中丰富的知识,巧妙而高效地解决各种问题。 此书为英文版,因为中文...
读者在阅读本书时应该特别关注正则表达式的设计原理、各种元字符和特殊构造的使用技巧,以及在实际编程中如何高效地运用正则表达式解决实际问题。同时,学习如何避免常见的错误和性能陷阱,提高编程效率和代码质量。
参考文献部分则为学习者提供了扩展阅读材料,以便更深入地理解正则表达式的原理和应用。有了这些基础知识,学习者可以更好地理解正则表达式在不同编程环境和应用软件中的作用,包括其在PHP中的运用。在PHP中,正则...
2. **解释器**:将用户输入的正则表达式分解并解释每个部分的含义,帮助用户理解其工作原理。 3. **调试器**:通过逐步执行正则表达式,显示每一步如何匹配文本,帮助定位潜在的问题。 4. **代码生成**:根据输入...
此调试工具的源码对易语言学习者来说是一份宝贵的资源,他们可以通过阅读和分析源码,深入理解正则表达式的实现原理,提升自己的编程技能。 在使用易语言正则表达式调试工具时,开发者需要注意以下几点: 1. **...
首先,让我们深入理解C++正则表达式库的核心特性。正则表达式库通常是C++标准库的一个扩展,提供了一种编程接口,使得程序员可以方便地在代码中使用正则表达式。这款小型库虽然体积小,但功能却不容小觑,它支持各种...