Upgrade to Pro — share decks privately, control downloads, hide ads and more …

正则表达式

Avatar for shhhz shhhz
June 30, 2021

 正则表达式

正则表达式的基础、历史以及自动机理论简介。

Avatar for shhhz

shhhz

June 30, 2021
Tweet

More Decks by shhhz

Other Decks in Technology

Transcript

  1. 基本用法 匹配数字 \d ! [0-9] 匹配字母 [a-z] "#$% 匹配单字字符(字母、数字或下划线) \w

    ! [0-9a-zA-Z_] $name = ””; [A-Z] &#$% Regular expressions originated in 1951. Regular expressions originated in 1951. Regular expressions originated in 1951.
  2. 基本用法 限定符 {n} 正好 n 次 Regular expressions originated in

    1951. \d{4} {n,} 至少 n 次 Regular expressions originated in 1951. \w{10,} {n,m} 至少 n 次,至多 m 次 Regular expressions originated in 1951. \w{5,8} * 等价于 {0,} \d* ? 等价于 {0,1} \d? + 等价于 {1,} \d+
  3. 基本用法 标记 [..] 匹配方括号内任意字符。 [Aa]pple 匹配 Apple 或者 apple [^..]

    匹配不在方括号内任意字符。 1[^13579]0 匹配 100、120、140、1a0 等 [..] 很多字符在方括号内都会失去本来的意义 [?.+] 匹配问号、点号或加号
  4. 基本用法 分组 (..) 记住和这个模式匹配的匹配项(捕获分组) Tel number is 800-820-8820 \d{3}-(\d{3}-(\d{4})) $2:8820

    $1:820-8820 (?:..) 匹配但不保存匹配项(非捕获分组) 分支条件 | 在两个或多个项之间进行选择。 (apple|banana|orange) (\d)\1 \:i 反向引用 800-820-8820 \d{3}-(?:\d{3}-(\d{4})) $1:8820 从左往右第一个匹配结果, 可以使用 g 来指定全局捕获
  5. 有趣的例子 1)匹配日期 Jan xx (01-31 或 1-31) • [12][0-9] •

    3[01] • 0?[1-9] Jan (0?[1-9]|[12][0-9]|3[01]) Jan ([12][0-9]|3[01]|0?[1-9]) 1 01 2 02 3 03 4 04 5 05 7 07 8 08 9 09 6 06 11 12 13 14 15 17 18 19 16 21 22 23 24 25 27 28 29 26 10 20 31 30 Jan 31
  6. 有趣的例子 1 01 2 02 3 03 4 04 5

    05 7 07 8 08 9 09 6 06 11 12 13 14 15 17 18 19 16 21 22 23 24 25 27 28 29 26 10 20 31 30 1 01 2 02 3 03 4 04 5 05 7 07 8 08 9 09 6 06 11 12 13 14 15 17 18 19 16 21 22 23 24 25 27 28 29 26 10 20 31 30 Jan ([123]0|[012]?[1-9]|31) Jan (0[1-9]|[12][0-9]?|3[01]?|[4-9])
  7. 基本用法 位置 ^ 匹配开始的位置 $ 匹配结束的位置 环视 (?=) 肯定顺序环视 (?<=)

    肯定逆序环视 (?!) 否定顺序环视 (?<!) 否定逆序环视 ^\d+$ 2019 2019.1.1 (零宽正向先行断言)(positive lookahead) (lookaround) its me! find me, not me! me(?=,) (?<=find\s)me me(?!\!) (?<!(its|not)\s)me 顺序(先行) 逆序(后行) (零宽正向后行断言) (零宽负向先行断言) (零宽负向后行断言) (positive lookbehind) (negative lookahead) (negative lookbehind)
  8. 贪婪匹配 贪婪量词(匹配优先量词):{m,n}、?、*、+ • 匹配 { “name”: “Regex” } “.*” “[^”]*”

    • 匹配 <div>Regex</div> <div>[^<div>]*</div> 非贪婪量词(忽略优先量词):{m,n}?、??、*?、+? “.*?” <div>.*</div> <div>.*?</div> <div>Regex</div></div> <div>Hello<div>Regex</div></div>
  9. 禁止回溯 • 原子捕获分组(atomic capturing groups) a(bc|b)c a(?>bc|b)c abcc ✅ ✅

    abc ✅ ❌ 又叫固化分组。像贪婪量词一样,但是不会进行回溯 • 理解表达式匹配的运作过程,理解需求,重写正则 (?>group) === (?=(group))\1
  10. 正则表达式的历史 1950s Stephen Cole Kleene 建立了自动机模型,使用该模型来识别(接收)一个语言 1950s Chomsky 将语言形式地定义为由一个字母表的字母组成的一些串的集合 Chomsky

    将他本人的形式语言的研究成果和 Kleene 的自动机的研究成果结 合起来,不仅确定了文法和自动机分别从产生和识别角度定义语言,而且证 明了文法与自动机的等价性。诞生了形式语言与自动机理论。 1950s
  11. Ken Thompson 发表了 《Regular Expression Search Algorithm》,描述了一种正 则表达式编译器 正则表达式的历史 1968

    由此也诞生了 qed,后来成了 Unix 中 ed 编辑器的基础 g/Regular Expression/p( Global Regular Expression Print )命令 独立为 grep
  12. DFA( Deterministic Finite Automata ) • 没有 ε 转移 •

    对于同一状态和同一输入,只会有一个转移 (a|b)*abb NFA DFA
  13. McMaughton-Yamada-Thompson 算法 归纳规则 已有正则表达式 s 和 t 的 NFA 分别为

    N(s) 和 N(t),构造 N(r): 1)并 当 r = s|t,N(r) 为
  14. 中缀表达式转后缀表达式 a*·(b|c·d) a*bcd·|· 1. 如果遇到字母,将其输出。 2. 如果遇到左括号,将其入栈。 3. 如果遇到右括号,将栈元素弹出并输出直到遇到左括号为止。左括号只弹出不输出。 4.

    如果遇到限定符,依次弹出栈顶优先级大于或等于该限定符的限定符,然后将其入栈。 5. 如果读到了输入的末尾,则将栈中所有元素依次弹出。 优先级:并 | < 连接符 · < 闭包 *
  15. 后缀表达式转 NFA • 如果为字母 s,构建基本 NFA N(s),并将其入栈 • 如果为 |,弹出栈内两个元素

    N(s)、N(t),构建 N(r) 将其入 栈(r = s|t) • 如果为 ·,弹出栈内两个元素 N(s)、N(t),构建 N(r) 将其入栈 (r = st) • 如果为 *,弹出栈内一个元素 N(s),构建 N(r) 将其入栈(r = s*) a*bcd·|· N(a) N(a*) N(a*) N(b) N(a*) N(b) N(c) N(d) N(a*) N(b) N(c) N(a*) N(b) N(cd) N(a*) N(b|(cd)) N(a*(b|(cd)))
  16. 更更有趣的例子 例:如何判断一个二进制是不是 3 的整数倍? • 一位二进制为 1 时,余 1 •

    一位二进制为 0 时,余 0 • 往右添加 1,原数乘 2 加 1,余 0 变余 1,余 1 变余 0,余 2 变余 2 • 往右添加 0,原数乘 2,余 0 变余 0,余 1 变余 2,余 2 变余 1 ^1((10*1)|(01*0))*10*$