【模式串匹配】正则表达式与正则表达式匹配

正则表达式是理论计算机科学和形式语言理论中的一个基本概念,由美国数学家Stephen Cole Kleene提出。

正则表达式定义

  正则表达式 (Regular Expression) 是符合正则文法的字符串, 它由三种基本的操作符(连接操作符“·”、选择操作符“|”‘、重复操作符“*”’)进行递归定义而成。正则表达式 的形式化定义如下:

  • 正则表达式:定义在符号集合 Σ ∪ { ϵ , ⋅ , ∣ , ∗ , ( , ) } \Sigma \cup\{\epsilon, \cdot, \mid, *,(,)\} Σ{ ϵ,,,,(,)}的字符串, 递归定义如下:
  1. 空字符 ϵ \epsilon ϵ 是正则表达式。任意字符 a ∈ Σ a \in \Sigma aΣ 是正则表达式;
  2. 如果 r 1 r_{1} r1 r 2 r_{2} r2 都是正则表达式, 则 ( r 1 ) 、 ( r 1 ⋅ r 2 ) 、 ( r 1 ∣ r 2 ) \left(r_{1}\right) 、\left(r_{1} \cdot r_{2}\right) 、\left(r_{1} \mid r_{2}\right) (r1)(r1r2)(r1r2) ( r 1 ∗ ) \left(r_{1} *\right) (r1) 亦是正则表达式。

正则表达式的语言

  正则表达式表示有穷或无穷多个字符串的集合, 具有比精确字符串更强大的描述能力。称正则表达式表示的字符串集合为正则表达式的语言。正则表达式 r r r 的语言用 L ( r ) L(r) L(r) 表 示, 定义如下:

  • 正则表达式的语言: 正则表达式 r r r 所表示的语言 L ( r ) L(r) L(r) 是字母表 Σ \Sigma Σ 上的字符串的集合。根据正则表达式 r r r 的结构, 递归定义如下:
  1. 如果 r = ϵ r=\epsilon r=ϵ, 则 L ( r ) = { ϵ } L(r)=\{\epsilon\} L(r)={ ϵ}, 即 r r r 表示空字符串。
  2. 如果 r = a ( a ∈ Σ ) r=a ( a \in \Sigma) r=aaΣ), 则 L ( r ) = { a } L(r)=\{a\} L(r)={ a}, 即 r r r 表示一个长度为 1 的字符串 “ a a a ”。
  3. 如果 r r r ( r 1 ) \left(r_{1}\right) (r1) 这种形式, 则 L ( r ) = L ( r 1 ) L(r)=L\left(r_{1}\right) L(r)=L(r1)
  4. 如果 r r r ( r 1 ⋅ r 2 ) \left(r_{1} \cdot r_{2}\right) (r1r2) 这种形式, 则 L ( r ) = { w 1 w 2 ∣ w 1 ∈ L ( r 1 ) , w 2 ∈ L ( r 2 ) } L(r)=\left\{w_{1} w_{2} \mid w_{1} \in L\left(r_{1}\right), w_{2} \in L\left(r_{2}\right)\right\} L(r)={ w1w2w1L(r1),w2L(r2)} 。其中 w 1 w 2 w_{1} w_{2} w1w2 表示由字符串 w 1 w_{1} w1 w 2 w_{2} w2 连接而成的字符串。“·”被称为链接操作符。
  5. 如果 r r r ( r 1 ∣ r 2 ) \left(r_{1} \mid r_{2}\right) (r1r2) 这种形式, 则 L ( r ) = L ( r 1 ) ∪ L ( r 2 ) L(r)=L\left(r_{1}\right) \cup L\left(r_{2}\right) L(r)=L(r1)L(r2) 。“|”被称为选择操作符。
  6. 如果 r r r ( r 1 ∗ ) \left(r_{1} *\right) (r1) 这种形式, 则 L ( r ) = { w 1 w 2 ⋯ w k ∣ k ≥ 0 , w i ∈ L ( r 1 ) , 1 ≤ i ≤ k } L(r)=\left\{w_{1} w_{2} \cdots w_{k} \mid k \geq 0, w_{i} \in L\left(r_{1}\right), 1 \leq i \leq k\right\} L(r)={ w1w2wkk0,wiL(r1),1ik} “*” 被称为重复操作符。

正则表达是匹配

  • 单正则表达式匹配:给定正则表达式 r r r, 对于任意的输入文本 T = t 1 t 2 ⋯ t n T=t_{1} t_{2} \cdots t_{n} T=t1t2tn, 找 出 L ( r ) L(r) L(r) 中的字符串在文本 T T T 中的出现位置,即: occur ⁡ ( r , T ) = { ( i , j ) ∣ t [ i , ⋯   , j ] ∈ L ( r ) } \operatorname{occur}(r, T)=\{(i, j) \mid t[i, \cdots, j] \in L(r)\} occur(r,T)={ (i,j)t[i,,j]L(r)}
  • 多正则表达式匹配:给定正则表达式集合 R = { r 1 , r 2 , ⋯   , r K } R=\left\{r_{1}, r_{2}, \cdots, r_{K}\right\} R={ r1,r2,,rK} ,对于任意的输入文本 T = t 1 t 2 ⋯ t n T=t_{1} t_{2} \cdots t_{n} T=t1t2tn, 找出 L ( r k ) ( 1 ≤ k ≤ K ) L\left(r_{k}\right)(1 \leq k \leq K) L(rk)(1kK) 中的字符串在文本 T T T 中的出现位 置, 即: occur ⁡ ( R , T ) = { ( i , j , k ) ∣ t [ i , ⋯   , j ] ∈ L ( r k ) , r k ∈ R } \operatorname{occur}(R, T)=\left\{(i, j, k) \mid t[i, \cdots, j] \in L\left(r_{k}\right), r_{k} \in R\right\} occur(R,T)={ (i,j,k)t[i,,j]L(rk),rkR}

  需要特别说明的是, 正则表达式匹配 (Regular Expression Matching), 也称正则表达 式搜索 (Regular Expression Searching), 它与正则表达式识别 (Regular Expression Recognizing)有显著的不同。

  • 正则表达式匹配是在输入文本 T T T 中搜索所有属于 L ( r ) L(r) L(r)子串 t [ i , ⋯   , j ] t[i, \cdots, j] t[i,,j],
  • 而正则表达式识别是指: 给定正则表达式 r r r, 对于任意的输入文本 T T T, 判断 T ∈ L ( r ) T \in L(r) TL(r) T ∉ L ( r ) T \notin L(r) T/L(r)

正则表达式的描述能力

  正则表达式描述能力强,语法灵活,能够表达更加精确和丰富的过滤规则。在语法能力上,正则表达式的描述能力最强,布尔表达式次之,精确字符串的描述能力最弱。这三种规则表示方法的语法能力具有包含的关系:

  • 精确字符串规则类 ⊂ \subset 布尔表达式规则类 ⊂ \subset 正则表达式规则类

正则表达式匹配的基本理论

  • 正则表达式的研究已经有几十年的历史,根据自动机和计算理论,正则表达式具有与自动机等价的计算能力,因此正则表达式匹配主要依靠有限状态自动机来完成。
  • 有限状态自动机分为两类:一类是非确定型有限自动机(Nondeterministic Finite Automaton,简称NFA),另外一类是确定型有限自动机(Deterministic Finite Automaton,简称DFA)。
  • NFA和DFA的区别在于:对于确定的状态和确定的输入,NFA有多个后继状态,而DFA则只有唯一的后继状态。NFA、DFA和正则表达式在计算能力上是等价的。

补充知识:什么是状态自动机?参考:https://zhuanlan.zhihu.com/p/47434856

  • 状态机是有限状态自动机的简称,是现实事物运行规则抽象而成的一个数学模型。先来解释什么是“状态”( State )。
  • 现实事物是有不同状态的,例如一个自动门,就有 open 和 closed 两种状态。我们通常所说的状态机是有限状态机,也就是被描述的事物的状态的数量是有限个,例如自动门的状态就是两个 open 和 closed 。
  • 状态机,也就是 State Machine ,不是指一台实际机器,而是指一个数学模型。说白了,一般就是指一张状态转换图。例如,根据自动门的运行规则,我们可以抽象出下面这么一个图。
    在这里插入图片描述
  • 自动门有两个状态,open 和 closed ,closed 状态下,如果读取开门信号,那么状态就会切换为 open 。open 状态下如果读取关门信号,状态就会切换为 closed 。
  • 状态机的全称是有限状态自动机,自动两个字也是包含重要含义的。给定一个状态机,同时给定它的当前状态以及输入,那么输出状态时可以明确的运算出来的。例如对于自动门,给定初始状态 closed ,给定输入“开门”,那么下一个状态时可以运算出来的。

NFA 非确定型自动机

五元组 < Q , Σ , δ : Q × Σ ∪ { ϵ } ↦ 2 Q , q 0 , F > <Q, \Sigma, \delta: Q \times \Sigma \cup\{\epsilon\} \mapsto 2^{Q}, q_{0}, F> <Q,Σ,δ:Q×Σ{ ϵ}2Q,q0,F>

  • Q为限状态集合;
  • Σ \Sigma Σ 为字母表 (也称字符集);
  • δ \delta δ 为状态转移函数,对于任意的输入字符 c ∈ Σ c \in \Sigma cΣ, 状态转移函数将当前状态映射到唯一的后继状态;
  • q 0 q_{0} q0 为初始状态;
  • F F F 为终止 (接受) 状态集合, 是状态集合 Q Q Q 的子集。
    在这里插入图片描述

DFA 确定型自动机

五元组 < Q , Σ , δ : Q × Σ ↦ Q , q 0 , F > <Q, \Sigma, \delta: Q \times \Sigma \mapsto Q, q_{0}, F> <Q,Σ,δ:Q×ΣQ,q0,F>
在这里插入图片描述
DFA与NFA的区别:

  1. 对于字母表的每个符号表示形式,DFA 中只有一个状态转换。NFA 无需指定根据某些符号做出反应。
  2. DFA 不能使用空字符串转换。 NFA 可以使用空字符串转换。
  3. DFA可以理解为一台机器。 NFA可以理解为同时计算的多台小型机器
  4. DFA 明确设置下一个可能的状态。 NFA 中,每对状态和输入符号可以具有许多可能的后续状态。
  5. DFA更难构建。NFA更容易构建。
  6. 如果字符串终止的状态与接受状态不同,则 DFA 将拒绝该字符串。 NFA 在所有分支死亡或拒绝字符串的情况下拒绝字符串。
  7. 执行输入字符串所需的时间更少。 执行输入字符串所需的时间更多。
  8. 所有DFA都是NFA。并非所有NFA都是DFA。
  9. DFA 需要更多空间。NFA 需要的空间比 DFA 少。
  10. DFA δ:QxΣ -> Q 即下一个可能的状态属于 Q。 NFA δ:QxΣ -> 2^Q 即下一个可能状态属于 Q 的幂集。

参考:

  1. 中国科学院大学刘燕兵 《模式串匹配与信息过滤》
  2. https://www.geeksforgeeks.org/difference-between-dfa-and-nfa/

猜你喜欢

转载自blog.csdn.net/qq_39328436/article/details/124390898