首页 › programming › 正则:程序员的黑白魔法

正则:程序员的黑白魔法——一条“100秒神课”深度解读

概述:为什么这条视频值得认真读一遍

在编程世界里,有一门技能几乎人人用过、人人怕过、人人骂过,却谁也离不开它——正则表达式(Regular Expression,简称 regex)。YouTube 上知识类频道 Fireship 的《Regex in 100 Seconds》正是把这门“黑白魔法”压缩进两分钟的神课:节奏极快、信息密度极高,评论区常年是一边“我看了五遍才消化”一边“这是我唯一看懂的正则入门”的两极景观。它常青的原因很朴素:只要你还需要处理文本——验证表单、解析日志、清洗数据、改配置——你就迟早会和正则狭路相逢。

但两分钟只能给你一张“地图”,不能给你“地形”。这篇文章的任务,是把这条视频里的每一句话拆开、放慢、溯源、批判:正则从哪里来(它其实是一门被数学定义过的语言)、它的两个引擎为什么性能天差地别、为什么它既是程序员的最爱又是生产事故的常客。看完本文,你没看过视频也能懂;看过视频,你会多懂一整层。

视频基本信息

项目 内容
视频标题 Regex in 100 Seconds(100秒讲完正则表达式)
频道 Fireship(主理人 Jeff Delaney)
发布时间 2020年12月前后(据频道页面)
播放量 数百万级,为其“100秒”系列常青头部(据频道页面,未实时核验精确数字)
时长 约2分钟
观看渠道 YouTube 检索 "Fireship Regex in 100 Seconds",或访问其官方频道页

(注:以上数据以频道页面公开信息为准,本文无法实时核验精确播放量,故只标注量级。)

核心主张拆解:两分钟里到底装了什么

这条视频的叙事结构极其紧凑,本质上是一堂“从零到能写”的速成课。按镜头顺序拆开,它讲了五层内容。

第一层:正则到底是什么——描述“模式”的语言

视频开宗明义:正则表达式是一种用符号描述文本模式的微型语言。它不是某家公司的产品,也不是某个库的 API,而是一种横跨几乎所有编程语言的通用记法。你写下 ^\d{3}-\d{4}$,任何语言都能读懂这句话:“以三个数字开头、中间一个连字符、后面跟四个数字、然后结束。”

视频在这里埋了一个重要的认知锚点:正则解决的不是“查找某个字符串”,而是“查找一类字符串”。前者用 Ctrl+F 就够了,后者才是正则存在的理由。这也是它难的根源——你从“字面思维”切换到“模式思维”,等于换了一种世界观。

第二层:字符与字符类——积木的最小单元

接下来视频快速演示了基础积木:普通字符按字面匹配;方括号 [abc] 表示“这个位置可以是 a、b 或 c”;\d 代表任意数字,\w 代表字母数字下划线,. 代表任意单个字符。这一层的要点是:正则的每个符号都在回答一个问题——“下一个字符长什么样”。把正则读对的方法,是从左到右逐位“过筛子”,而不是把它当一个整体去猜。

第三层:量词与贪婪——正则真正的威力区

然后是威力最大的部分:量词。* 表示零次或多次,+ 表示一次或多次,? 表示零次或一次,{2,5} 表示两次到五次。视频在这里出现了一个几乎所有初学者都会踩、但两分钟课程没时间展开的深坑——贪婪匹配:默认情况下量词会“吃掉尽可能多”的字符,想让它“吃少一点”,要在量词后面加问号变成懒惰模式。<.*> 和 <.*?> 在解析 HTML 时会给出完全不同的结果。这个加号后的小问号,是新手与老手写出的正则最常见的一处分水岭。

第四层:锚点与分组——给模式装上骨架

量词解决“重复”,锚点解决“位置”:^ 锚定行首,$ 锚定行尾,\b 锚定单词边界。分组用圆括号实现,除了把几个符号捆成一个整体,还能“捕获”匹配内容供后续引用,配合 | 实现“或”的分支。至此,视频已经拼出了完整的能力图谱:字符描述内容,量词描述重复,锚点描述位置,分组描述结构。

第五层:断言、场景与工具——从会写到会用

最后视频亮出了高级技能——环视断言(lookahead / lookbehind):只匹配“后面跟着 XX”的位置,却不把 XX 吃进结果。然后给出了正则的三大典型战场:表单验证(邮箱、手机号)、搜索替换(编辑器里的批量改写)、日志与数据的抽取清洗。结尾不忘安利两个神器:regex101 这类在线调试工具(实时高亮、逐条解释每个符号)和“别背语法、要用时现查”的实用主义态度。

知识与理论溯源:这条视频背后七十年的学术与工程史

两分钟的视频当然没时间讲历史,但正则的每个符号背后都站着真实的人和论文。这一节是本文要给你的“多懂的一层”。

1. 数学源头:Kleene 的“正则事件”(1951)

正则不是程序员发明的,是数学家发明的。1951年,美国兰德公司(RAND)的数学家斯蒂芬·科尔·克莱尼(Stephen Cole Kleene)在研究神经网络建模时,提出了一类可以用极简规则描述的“正则事件”(regular events),后于1956年发表为论文《Representation of Events in Nerve Nets and Finite Automata》。他证明了:这类语言恰好等于有限自动机所能识别的语言。这个等价关系是整个正则帝国的地基——你在键盘上敲的每个 * 和 +,都是一个数学对象。

2. 工程落地:Ken Thompson 把数学塞进编辑器(1968)

真正让正则“飞入寻常百姓家”的是 Unix 传奇肯·汤普森(Ken Thompson)。1968年,他在 CACM 发表论文《Regular Expression Search Algorithm》,给出了把正则编译成 IBM 7094 机器码的高效实现,并把它做进了 QED 编辑器。随后在贝尔实验室的 ed 编辑器里,搜索命令的用法是“全局(global)搜索正则表达式(regular expression)并打印(print)结果”——这个命令的缩写 g/re/p,就是日后命令行神器 grep 的名字。你在终端里敲下的每一次 grep,都是在向 1968 年的贝尔实验室致敬。

3. 方言大分裂:一套语法,各说各话

正则随后随 Unix 扩散,但也开始了几十年的“方言分裂”:POSIX 定义了基础正则(BRE)与扩展正则(ERE)两套标准;Perl 横空出世后加入大量糖衣与高级特性,形成了事实上的 PCRE(Perl Compatible Regular Expressions)流派;JavaScript、Python、Java、.NET 各自实现了“大致像 Perl 但各有出入”的版本。同一条正则,换一个语言可能语义就变——这正是视频里“别背语法、用时查工具”态度背后的历史原因:不是你不努力,是这门语言确实没有唯一标准。

4. 引擎的两条路线:回溯派与自动机派

这是理解正则性能的钥匙,也是视频中完全没讲、但任何在生产环境用过正则的人都该懂的一层。实现正则的引擎分两大流派:

2010年前后,谷歌工程师拉斯·考克斯(Russ Cox)在 swtch.com 发表的著名三部曲《Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby...)》系统梳理了这段历史:Thompson 1968 年的算法本来就是线性的,后来的主流语言却普遍选择了容易实现高级功能的回溯路线,等于在性能上“开倒车”。这篇文章是正则领域被引用最多的工程文献之一。

5. 血的教训:回溯爆炸引发的两次著名宕机

理论爆炸是真的会炸的。2016年7月,Stack Overflow 因一条性能问题正则在负载评估环节触发灾难性回溯,页面大面积不可用,事后官方复盘公开了全过程;2019年7月2日,Cloudflare 全球边缘网络因一条正则(内含嵌套量词叠加的病态模式)导致边缘节点 CPU 打满,接近全网宕机约27分钟,其官方博客以《Details of the Cloudflare outage on July 2, 2019》做了极其坦诚的复盘。两次事故的模式高度一致:一条“在测试数据上跑得好好的”的正则,遇到某段“恰好恶意”的输入,回溯次数指数级增长,CPU 瞬间归零可用性。这类攻击有个专门的名字:ReDoS(Regular Expression Denial of Service,正则拒绝服务)。

批判性审查:这条视频哪里靠谱,哪里埋着坑

证据充分、值得放心的部分

视频对正则语法的讲解本身零瑕疵——字符类、量词、锚点、分组、断言的表述全部准确,这是 Fireship 一贯的工程严谨度。“用 regex101 调试”的建议也完全正确:正则是典型的“看会了≠会写”技能,逐符号可视化反馈是最高效的学习路径,这个建议值得再加倍强调。

被压缩掉的关键一课:引擎是怎么“想”的

100秒课程最大的取舍,是只教“怎么写”,没教“引擎怎么读”。而上面两起宕机事故证明:只会写、不懂引擎,等于拿着能走火的工具不知道枪里有没有子弹。(a+)+b 这种嵌套量词模式,对普通输入毫无异样,对一串 "aaaaaaaaaaaaaaaaaaaaX" 却会让回溯型引擎卡到天荒地老——同一份代码,换个输入就是事故。这不是初学者才需要的知识,而是每一个把正则投放到生产环境的人的必修课。

被一带而过的深坑:邮箱验证

视频把邮箱验证作为典型场景,但没说的是:“用一条正则完美验证邮箱”本身就是社区里被嘲笑了二十年的经典陷阱。RFC 5322 定义的合法邮箱地址复杂到理论上需要递归才能完全描述;业界共识早已是“用一条宽松正则做初筛 + 发送确认邮件做真验证”。程序员圈流传的名言出自 Netscape 早期工程师 Jamie Zawinski:

“有些人遇到问题时想:‘我知道,我用正则吧。’现在他们有两个问题了。”

xkcd 漫画也曾专门调侃“用正则解析 HTML”的自噬行为。这些调侃的共同内核是:正则适合正则语言层面的任务,一旦任务涉及任意深度的嵌套结构(HTML、JSON、配对括号),正则在理论上就注定力不从心——这又要回到 Kleene 的等价性定理:有限自动机没有栈,数不了括号层数。你嘲笑的每个“正则解析 HTML”的段子,其实都是 1956 年那篇数学论文早已证明的定理。

值得补上的另一面:它其实没那么可怕

大量“正则恐惧症”来自可读性差的超长正则。但工程实践里有一条被低估的纪律:正则的复杂度应该被控制在“一眼能读”的范围内,超出的部分应该拆成多条简单正则加普通代码,或者直接用字符串 API(split、indexOf、模板匹配)解决。社区 surveys 中“程序员最怕的正则”大多是人祸——把三百个业务规则硬塞进一条模式。正则不是用来炫技的一行流,是用来消灭重复样板代码的工具;当它开始制造样板般的晦涩时,就该退场了。

认知提升与实用启示:三条可以立刻执行的建议

建议1:写正则前,先在心里画状态机

看懂一条复杂正则的秘诀,是把“模式”翻译成“状态流转”:我从行首出发,此刻期待什么字符,吃到它之后进入什么状态,什么情况宣告失败。下次面对一条看不懂的正则,别整段盯着看,用 regex101 的高亮逐步喂样例字符串,观察哪些位置点亮、哪些位置熄灭——你实际上是在观察一台自动机的运转。理解从“背符号”升级为“走状态”,正则就从咒语变成了透明的机器。

建议2:对来自外部的输入,默认它会攻击你的正则

给自己立一条工程铁律:凡是用在服务端、处理不可信输入的正则,写完后必须做两件事——第一,检查是否存在嵌套量词((a+)+、(a|a)*、(.*)* 这类结构);第二,用超长重复样本压测一遍耗时。如果你的语言/运行时有条件,优先选择线性引擎:Go 的 regexp、Rust 的 regex、谷歌 RE2 天生免疫 ReDoS;必须用回溯引擎时,把匹配调用放进超时保护里。Cloudflare 那条炸掉半个边缘网络的正则,上线前没人觉得它会出事。

建议3:把正则当“手术刀”,别当“瑞士军刀”

正则最甜的场景有三类:格式明确的短文本验证(日期、编号、版本号)、编辑器与命令行里的批量搜索替换(一次顶一小时手工)、日志与数据的结构抽取(配合分组捕获)。超出这三类的诱惑——解析 HTML、校验复杂业务规则、“一行搞定”的炫技——都先问自己一句:普通代码是不是更清楚?可读性是团队资产,一行别人看不懂的“优雅”正则是团队负债。

视频论证结构与知识关系图

flowchart TD
    A["Kleene 正则集<br/>1951"] --> B["Thompson 塞进编辑器<br/>1968"]
    B --> C["grep 诞生<br/>g/re/p"]
    C --> D["方言大分裂<br/>POSIX 与 PCRE"]
    D --> E1["回溯引擎<br/>功能多 会爆炸"]
    D --> E2["自动机引擎<br/>线性 永不爆炸"]
    E1 --> F["嵌套量词<br/>回溯爆炸"]
    F --> G["ReDoS 事故<br/>2016 与 2019 两次宕机"]
    E2 --> H["RE2 等线性实现<br/>生产安全选项"]
    G --> I["三条纪律<br/>查嵌套 压测 限超时"]

延伸阅读

  1. Russ Cox《Regular Expression Matching Can Be Simple And Fast》三部曲(swtch.com/~rsc/regexp/)——把本文“两种引擎”一节展开成三篇神作,读完你会彻底理解正则的性能本质,是进阶的第一必读。
  2. regex101.com——视频里推荐的在线调试器,逐符号解释 + 实时匹配 + 回溯步数统计;建议把本文提到的 (a+)+b 喂进去,亲眼看一次回溯爆炸。

参考来源

  1. Fireship 官方频道页 — 《Regex in 100 Seconds》可在频道内直接检索观看
  2. Russ Cox 正则系列文章 — 《Regular Expression Matching Can Be Simple And Fast》等三部曲原文
  3. Cloudflare 官方博客 — 复盘文章《Details of the Cloudflare outage on July 2, 2019》,2019年正则宕机事故的一手资料
  4. regular-expressions.info — 老牌正则教程站,各语言方言差异的系统对照
  5. Ken Thompson《Regular Expression Search Algorithm》,Communications of the ACM, 1968 — 正则工程化的开山论文(ACM 数字图书馆可检索)

本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵爱卫生(微信ID: gprshome201101)维护,聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入