NFA与字符串匹配

323 阅读4分钟

什么是自动机?

自动机是有限状态机(FSM)的数学模型。
FSM 是给定符号输入,依据(可表达为一个表格的)转移函数“跳转”过一系列状态的一种机器。在常见的 FSM 的“Mealy”变体中,这个转移函数告诉自动机给定当前状态和当前字符的时候下一个状态是什么。
逐个读取输入中的符号,直到被完全耗尽(把它当作有一个字写在其上的磁带,通过自动机的读磁头来读取它;磁头在磁带上前行移动,一次读一个符号)。一旦输入被耗尽,自动机被称为“停止”了。
依赖自动机停止时的状态,称呼这个自动机要么是“接受”要么“拒绝”这个输入。如果停止于“接受状态”,则自动机“接受”了这个字。在另一方面,如果它停止于“拒绝状态”,则这个字被“拒绝”。自动机接受的所有字的集合被称为“这个自动机接受的语言”。

以上引自百度百科词条自动机

NFA与字符串匹配

字符串匹配过程

通常情况下,我们都会遇到需要进行字符串处理的工作。

例如,一个人力资源表格,我们要找到职级为e1,且曾经在HIC或LLC公司(字段名'company')供职的员工。

那么,我们可能会写出这么一段查询 company in ('HIC' | 'LLC')

很显然,这里使用的匹配式子借用了正则表达式来表示。

那么,为什么我们需要借助正则表达式?它又和上面说的自动机理论有何瓜葛?

先喝口茶,且听我慢慢道来。

正则表达式

正则表达式是用来描述某种特定字符串模式的形式语言。

通常来说,我们使用的正则表达式都需要回溯机制,因为通用型的正则引擎都需要处理分组捕获的问题。这个问题我们先按下不表,目前我们只考虑下文给出的5中基本模式。

  • concat(.)

下图表示a.b

![](https://pic1.zhimg.com/v2-f3d2413e9157fa29f5302654809abdf1_b.png)

option(?)

下图表示``a?`

![](https://picb.zhimg.com/v2-c6cc653c0009132c606710c0e9028d15_b.png)

cleen(*)

下图表示``a*`

![](https://pic4.zhimg.com/v2-91b80a465291135babe5be473d532a58_b.png)

onemore(+)

下图表示``a+`

![](https://pic2.zhimg.com/v2-b22f48a130497b5f2401d0d8b538e16c_b.png)

or(|)

下图表示(a | b)

![](https://pic3.zhimg.com/v2-552695c15098e1f5b53376eb85cb8aad_b.jpg)

为什么需要NFA?

由上可知,如果我们要完成正则表达式所描述的模式匹配工作,则一定需要由某种机制来支持。如果,我们进一步将这个模式匹配的过程看作一个停机接受问题来处理的话。那么,我

们会发现将模式串视作一连串字符输入。同时,将待匹配字符串的每一个匹配结果视作一个状态。这里,我们将等待匹配开始计作开始状态S

回到最初的问题匹配('HIC' | 'LLC'),实际就是如下的NFA接受带匹配串输入,最后判断是否accept的问题。

![](https://pic4.zhimg.com/v2-c2f0020d2f1c2f95979435dca9b5a6fc_b.jpg)

NFA是什么?

言归正传,我们的目的是通过字符匹配过程理解NFA起的作用,以及NFA对于regex的一种表示。

从上文可知,NFA可以定义为如下的五元组[公式]

其中[公式]表示这个NFA能够接受的字母表,etc:'a','b','c'...'z'。

[公式]表示其中所有可达状态的集合,比如上图中的LR_0,LR_1..。

[公式]表示所有可接受的状态转移的集合,比如图中➡️表示的信息。

![](https://pic4.zhimg.com/v2-c2f0020d2f1c2f95979435dca9b5a6fc_b.jpg)

[公式]表示起始状态,任何状态机的起始状态都只有一个,如图中LR_0

[公式]表示接受状态,这个状态可以有多个。它表示一个输入字符串是否匹配当前自动机所定义的语言。当输入串消耗完毕时,如果最后状态是接受。那么,我们说这个串符合当前自动机表示的正则表达式或者说符合某个字符串模式。如图中LR_9

NFA ==? 匹配过程

如图所示,假定输入串为HLC.

![](https://pic4.zhimg.com/v2-42e02b6b9f920e537db642a280966e8e_b.png)

参考资料

1. 《编译器设计》第二版

2. 《编译器设计基础》

3. 百度百科

4. 《语言与机器---计算机科学导论》