04-正则引擎内部初探

理解正则引擎的内部原理将帮助你写出更高效的表达式,并且帮助你快速调试正则表达式中的异常。

在接下去的每一个章节中我们介绍一个新的正则特性,之后我们会解释引擎处理这个特性的详细过程。理解这些原理之后,我们便可以脱离正则可视化工具快速编写正则表达式。虽然理解引擎的原理有些难度,但是它可以帮助我们避免一些常见的错误。

在了解了这些基础知识之后,我们会介绍许多有意思的应用实例,你可以快速的把这些例子应用到你的项目中去。

4.1 引擎的分类

虽然正则引擎有很多种不同的实现,但是大体可以分为两类:文本驱动的引擎(text-directed)和正则驱动的引擎(regex-directed)。几乎所有的现代正则引擎都采用正则驱动引擎,这是因为一些非常有用的特性只能在这种引擎上实现,例如lazy quantifiersbackreferences

4.1.1 正则驱动的引擎(regex-directed engine)

一个正则表达式引擎通过遍历正则表达式完成匹配,它尝试将表达式中的下一个token和字符串中的下一个字符进行匹配。如果当前token可以匹配成功,那么引擎将移动至下一个token,并且把这个token和字符串中的下一个字符进行匹配。如果匹配失败,那么正则引擎会在正则和字符串中进行回溯,并且重新进行路径搜索。关于正则的回溯之后的章节会详细展开。

4.1.2 文本驱动的引擎(text-directed engine)

一个文本驱动的引擎通过遍历文本完成匹配。在匹配下一个字符之前,他会尝试表达式中的所有排列。一个文本驱动的引擎没有回溯过程,所以他的匹配过程相对简单。在大多数情况下两种引擎的匹配结果是相同的。

本教程主要讨论正则驱动的引擎,所以默认情况下我们提到的引擎都是正则驱动引擎,除非两种引擎的匹配结果不一致。只有当我们使用选择符,并且两个选项匹配到同一个位置时才会发生这种情况。

4.2 正则表达式总是匹配最左端的匹配结果

正则表达式总是匹配最左端的匹配结果,无论后面是否有更好的匹配结果,这是一个非常重要的特性。当正则引擎匹配一个字符串的时候,它将从字符串的最左边开始搜索。引擎将正则中所有的排列与字符串的第一个字符相匹配。如果有一种排列匹配成功,引擎将继续匹配字符串中的下一个字符。下一步引擎将字符串中的下一个字符与正则中的所有排列进行匹配。最终引擎将返回最靠左的匹配结果。

现在我们来举一个例子。我们使用表达式 cat 去匹配字符串 He captured a catfish for his cat 。首先引擎使用 c 去匹配字符串中第一个字符 H ,此时匹配不成功而且没有其他的排列(因为c只包含一个字面量字符)。之后引擎匹配token c 和字符 e ,同样也失败了,后面的空格也是如此。当引擎尝试匹配第四个字符的时候token c 匹配 c 成功了,所以引擎继续把第二个token a 与字符串中第5个字符 a 匹配,匹配也成功了。但是第三个token t 不能和第六个字符 p 匹配。此时引擎已经知道表达式无法和字符串中的前四个字符匹配,因此引擎将重新把第一个token c 和第5个字符 p 进行匹配,直到第15个字符时 c 才匹配成功,接下来 at 也匹配成功。

此时这个正则可以从字符串的第15个字符开始匹配成功,于是引擎非常“急切”的报告匹配成功。引擎不会继续向后搜索(即使后面会出现更好的匹配结果),因为它认为这个结果已经足够好了。

在这个例子当中两种正则引擎的搜索结果是相同的。正则的这种工作模式很大程度上决定了它的匹配结果,在之后例子中有一些匹配结果可能使你感到意外,但是只要你牢记这个搜索规则,你就可以用逻辑推导引擎的匹配结果。

预告

下一期我们会学习字符集。字符集以及字符集取反的作用非常强大,同时也很容易被人忽视。

如果文章出现错误,请给我提Issues - -
Github地址

原文

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值