3.表达式的匹配原理

本文探讨了正则表达式的两大引擎类型:NFA与DFA,并解释了它们的工作原理及特点。NFA引擎采用表达式主导的方式,通过回溯实现丰富的特性;而DFA引擎则采用文本主导的方法,虽然速度快但特性相对较少。

正则表达式的匹配原理

1. 概述

1.1 不同语言或工具中使用正则表达式的注意事项

  • 支持的元字符及其意义, 这通常称为正则表达式的 “流派”
  • 交互方式(如何进行正则表达式的操作, 容许进行哪些操作, 操作的目标文本类型等)
  • 正则表达式引擎如何将表达式应用到文本

1.2 引擎类型

引擎类型程序
DFAawk(大多数版本)、egrep(大多数版本)、flex、lex、MySQL、Procmail
传统型 NFAGUN Emace、Java、grep(大多数版本)、less、moer、.NET、PCRE library、Perl、PHP、Python、Ruby、sed、vi
POSIX NFAmawk、Mortice Kern Systems’utilities、GNU Emacs 明确指定时使用
DFA/NFA 混合GUN awk、GUN grep/egrep、Tcl

1.3 各引擎通用原则

  1. 优先选择最左端的匹配结果(最靠开头)
  2. 标准匹配量词的匹配优先(*、+、? 和{m, n}), 贪婪模式
  3. 在多选结构中,不要将大范围的表达式放在小范围表达式范围之后,会导致永远无法匹配

1.4 引擎的构造

  • 文字文本 : 字符是否与当前尝试匹配的字符相同
  • 字符组、点号、Unicode属性及其他 : 只匹配一个字符
  • 捕获型括号 : 用于捕获文本的括号(而不是用于分组的括号)不会影响匹配的过程
  • 锚点 : 简单锚点(^、$、\G、\b、…) 只检查目标字符串中的特定位置情况,或者是比较两个相邻的字符(\<、\b…); 复杂锚点(环视)可以包含任意复杂的子表达式, 所有它们也可以任意复杂
  • 括号、返向引用和忽略优先量词

2. 表达式主导与文本主导

2.1 非确定型有穷自动机 : NFA引擎, 表达式主导

  • 表达式的控制权在不同的元素之间转换, 所以称为 “表达式主导”
  • 引擎查看表达式一部分—>同时检查当前文本是否匹配表达式的当前部分—>是则继续匹配,直到表达式的所有部分都能匹配,则匹配成功
  • NFA要翻来覆去吃字符、吐字符,速度慢,但是特性丰富,所以反而应用广泛
NFA 引擎在操作上的优点
  1. 实质上,在表达式主导的匹配过程中,每一个子表达式都是独立的, 子表达式之间不存在内在联系,只是整个正则表达式的组成部分
  2. 子表达式与正则表达式的控制结构的层级关系控制了整个匹配过程(控制结构包括多选分支、括号以及匹配量词)

2.2 确定型有穷自动机 : DFA引擎, 文本主导

  • 引擎查看表达式一部分—>使用文本去匹配正则—>把有可能的匹配串全部标注出来—>再匹配正则表达式的下一个部分—>根据新的匹配结果更新标注
  • DFA引擎对于文本串里的每一个字符只需扫描一次,比较快,稳定、但特性较少

2.3 NFA引擎的回溯(backtracking)

  • NFA 引擎最重要的性质是, 它会依次处理各个子表达式或组成元素,遇到需要在两个可能中进行选择的时候,它会选择其一,同时记住另一个,以备稍后可能的需要
  • 需要做出选择的情形包括量词和多选结构(决定是否尝试另一次匹配和决定选择哪个多选分支, 留下哪个稍后尝试)
  • 如果正则表达式中余下的部分最终匹配失败,引擎会回溯到之前做出选择的地方,选择其他的备用分支继续尝试
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值