Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
正则表达式
Search
shhhz
June 30, 2021
Technology
0
34
正则表达式
正则表达式的基础、历史以及自动机理论简介。
shhhz
June 30, 2021
Tweet
Share
More Decks by shhhz
See All by shhhz
概率与随机
shhhz
0
47
游戏中的奥秘
shhhz
0
51
Seam Carving 算法
shhhz
0
280
Other Decks in Technology
See All in Technology
freeeのアクセシビリティの現在地 / freee's Current Position on Accessibility
ymrl
2
200
KubeCon + CloudNativeCon Japan 2025 Recap Opening & Choose Your Own Adventureシリーズまとめ
mmmatsuda
0
280
【5分でわかる】セーフィー エンジニア向け会社紹介
safie_recruit
0
27k
american aa airlines®️ USA Contact Numbers: Complete 2025 Support Guide
aaguide
0
150
Delegating the chores of authenticating users to Keycloak
ahus1
0
140
Geminiとv0による高速プロトタイピング
shinya337
1
270
Model Mondays S2E04: AI Developer Experiences
nitya
0
140
OPENLOGI Company Profile for engineer
hr01
1
34k
関数型プログラミングで 「脳がバグる」を乗り越える
manabeai
1
190
さくらのIaaS基盤のモニタリングとOpenTelemetry/OSC Hokkaido 2025
fujiwara3
3
440
How Do I Contact HP Printer Support? [Full 2025 Guide for U.S. Businesses]
harrry1211
0
120
American airlines ®️ USA Contact Numbers: Complete 2025 Support Guide
airhelpsupport
0
380
Featured
See All Featured
[RailsConf 2023] Rails as a piece of cake
palkan
55
5.7k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
Music & Morning Musume
bryan
46
6.6k
A Tale of Four Properties
chriscoyier
160
23k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.5k
Embracing the Ebb and Flow
colly
86
4.7k
VelocityConf: Rendering Performance Case Studies
addyosmani
332
24k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.4k
How to Ace a Technical Interview
jacobian
278
23k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
2.9k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
10
950
Testing 201, or: Great Expectations
jmmastey
43
7.6k
Transcript
{正则表达式} @孙恒哲
使用 历史 自动机
正则表达式的使用
使用场景 正则表达式赋予使用者描述和分析文本的能力。 文本处理 • 查找文本(区分大小写、符合特定位置) • 提取文本(邮件中的字段) • 替换文本(金融货币)
基本用法 匹配数字 \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.
基本用法 匹配任意字符(除换行符) . 匹配空白字符(空格、制表符、换页符和换行符) \s Regular expressions originated in 1951.
基本用法 限定符 {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+
基本用法 标记 [..] 匹配方括号内任意字符。 [Aa]pple 匹配 Apple 或者 apple [^..]
匹配不在方括号内任意字符。 1[^13579]0 匹配 100、120、140、1a0 等 [..] 很多字符在方括号内都会失去本来的意义 [?.+] 匹配问号、点号或加号
基本用法 分组 (..) 记住和这个模式匹配的匹配项(捕获分组) 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 来指定全局捕获
有趣的例子 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
有趣的例子 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])
有趣的例子 2)判断一个数是否是合数(非质数) ^.?$|^(..+?)\1+$ 3)判断 11x + 2y + 5z =
115 是否有自然数解 ^(.*)\1{10}(.*)\2{1}(.*)\3{4}$
基本用法 位置 ^ 匹配开始的位置 $ 匹配结束的位置 环视 (?=) 肯定顺序环视 (?<=)
肯定逆序环视 (?!) 否定顺序环视 (?<!) 否定逆序环视 ^\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)
更有趣的例子 例:金融货币格式化 需求:每隔三位添加一个逗号 1234567 -> 1,234,567 1 234 567 3n
(?<= ) (?= ) $ \d+ (\d{3})+
贪婪匹配 贪婪量词(匹配优先量词):{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>
回溯 正则:ab{1,3}bbc 文本:abbbc 原因:NFA 引擎的实现方式
回溯 正则:^(\d+)*$ 文本:123456789! 123456789 12345678 9 1234567 89 1234567 8
9 正则:^(\d+?)*$ \d+ (\d+)*
禁止回溯 • 原子捕获分组(atomic capturing groups) a(bc|b)c a(?>bc|b)c abcc ✅ ✅
abc ✅ ❌ 又叫固化分组。像贪婪量词一样,但是不会进行回溯 • 理解表达式匹配的运作过程,理解需求,重写正则 (?>group) === (?=(group))\1
正则表达式的历史
Warren McCulloch与 Walter Pitts 将神经系统中的神经元描述成小而简单的自动控制元。 正则表达式的历史 1940s
正则表达式的历史 1950s Stephen Cole Kleene 建立了自动机模型,使用该模型来识别(接收)一个语言 1950s Chomsky 将语言形式地定义为由一个字母表的字母组成的一些串的集合 Chomsky
将他本人的形式语言的研究成果和 Kleene 的自动机的研究成果结 合起来,不仅确定了文法和自动机分别从产生和识别角度定义语言,而且证 明了文法与自动机的等价性。诞生了形式语言与自动机理论。 1950s
Ken Thompson 发表了 《Regular Expression Search Algorithm》,描述了一种正 则表达式编译器 正则表达式的历史 1968
由此也诞生了 qed,后来成了 Unix 中 ed 编辑器的基础 g/Regular Expression/p( Global Regular Expression Print )命令 独立为 grep
正则表达式与自动机
形式语言与自动机 形式语言 自动机 正则表达式的核心是有穷自动机
• 一个初始状态 NFA( Nondeterministic Finite Automata ) • 一个或多个终结状态 •
状态转移函数 (a|b)*abb a
ε-NFA 除了能到达多个状态之外,NFA 还能接受空符号 ε (a+|b+)
DFA( Deterministic Finite Automata ) • 没有 ε 转移 •
对于同一状态和同一输入,只会有一个转移 (a|b)*abb NFA DFA
McMaughton-Yamada-Thompson 算法 McMaughton-Yamada-Thompson 算法可以将任何正则表达式转变为接受相同语言的 NFA。它分为两个规则: 基本规则 1)对于表达式 ε,构造下面的 NFA: 2)对于非
ε,构造下面的 NFA:
McMaughton-Yamada-Thompson 算法 归纳规则 已有正则表达式 s 和 t 的 NFA 分别为
N(s) 和 N(t),构造 N(r): 1)并 当 r = s|t,N(r) 为
McMaughton-Yamada-Thompson 算法 2)连接 当 r = st,N(r) 为 3)闭包 当
r = s*,N(r) 为
正则表达式转自动机 a*(b|cd) * · b · c d | a
中缀表达式转后缀表达式 a*·(b|c·d) a*bcd·|· 1. 如果遇到字母,将其输出。 2. 如果遇到左括号,将其入栈。 3. 如果遇到右括号,将栈元素弹出并输出直到遇到左括号为止。左括号只弹出不输出。 4.
如果遇到限定符,依次弹出栈顶优先级大于或等于该限定符的限定符,然后将其入栈。 5. 如果读到了输入的末尾,则将栈中所有元素依次弹出。 优先级:并 | < 连接符 · < 闭包 *
后缀表达式转 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)))
NFA 转 DFA 子集构造法算法可以将 NFA 转变为等价的 DFA。 NFA DFA
更更有趣的例子 例:如何判断一个二进制是不是 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*$
推荐网站 正则表达式可视化 https://regexper.com https://regex101.com/ 在线运行、调试、分析
THANK YOU!