Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
正则表达式
Search
shhhz
June 30, 2021
Technology
53
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
正则表达式
正则表达式的基础、历史以及自动机理论简介。
shhhz
June 30, 2021
More Decks by shhhz
See All by shhhz
概率与随机
shhhz
0
66
游戏中的奥秘
shhhz
0
68
Seam Carving 算法
shhhz
0
330
Other Decks in Technology
See All in Technology
フルカイテン株式会社 エンジニア向け採用資料
fullkaiten
0
12k
幾何アルゴリズムで なめらかなピン操作を / iOSDC Japan 2026 / smoothpin
kazumanagano
0
360
え、こんなに早く改修できるの?──新人エンジニアとスクラムマスターの2人が語る、AI×アジャイル開発の現場
ysasago
2
540
データ_AIの事業の勝敗をわけるもの
nek0128
1
460
AIエージェントの自己改善をどう設計するか / How to Design Self-Improvement for AI Agents
22mi
25
16k
現場で役立つ技術負債の効果的な返済方法
masuda220
PRO
9
4.7k
C#未経験の僕がAIに読めるコードを書かせるまで
maguroalternative
0
110
開発投資の期待値を上げるプロダクトロードマップづくり ~プロダクトエンジニアが越境して事業を伸ばす~
kekekenta
1
230
絵ではじめるKubernetesセキュリティ
aoi1
4
690
作って終わりじゃないサーバーレス 〜9年運用する大規模EC物流API基盤の設計・運用のリアル〜
zozotech
PRO
0
300
品質と信頼性を地続きにする
grimoh
2
820
なぜ「決定性」が 決定的に重要なのか? Durable Execution 基盤の数理的理解 #serverlessjp / ServerlessDays Tokyo 2026
ytaka23
3
930
Featured
See All Featured
The Mindset for Success: Future Career Progression
greggifford
PRO
0
500
Deep Space Network (abreviated)
tonyrice
0
310
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
580
Ruling the World: When Life Gets Gamed
codingconduct
0
340
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
A Modern Web Designer's Workflow
chriscoyier
699
190k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
530
Done Done
chrislema
186
16k
Code Review Best Practice
trishagee
74
20k
The Cost Of JavaScript in 2023
addyosmani
55
10k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
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!