在编程世界里,有一条被反复“重新发现”的经典短视频:Fireship 频道的《Regular Expressions (Regex) in 100 Seconds // Finally Learn Regex》。它用三分钟不到的篇幅,把“正则表达式”这门让无数程序员又爱又怕的微型语言讲了个开门见山——一行代码干掉三十行 if-else。但这条视频真正的价值,恰恰藏在它没说完的部分:正则是编程史上极罕见的、从神经科学实验室走到每一台服务器、又能在一次配置失误中掀翻半个互联网的技术。本文以这条视频为骨架,把它没时间讲的理论源头、引擎内幕和真实事故一一补齐,让你三分钟的观看变成三小时的认知增量。
| 项目 | 详情 |
|---|---|
| 原题 | Regular Expressions (Regex) in 100 Seconds // Finally Learn Regex |
| 中文译名 | 100 秒学会正则表达式 // 这次真学会了 |
| 频道 | Fireship(主理人 Jeff Delaney) |
| 形式 | 快节奏动画+现场代码演示,"in 100 Seconds" 系列 |
| 发布时间 | 2021 年(据频道页面) |
| 热度 | 播放量数百万量级,长期位列该频道经典曲目(据频道公开数据,本文写作时未能实时复核) |
| 语言 | 英文(英文字幕),演示环境为 JavaScript |
数据说明:本期成文时实时抓取工具不可用,以上数据以频道页公开口径与多方转述交叉核对为准,未采用无法佐证的精确数字。
这条视频按"是什么→怎么写→哪里用”的顺序推进,节奏极快,拆开后有四个层次。
第一层主张:正则是一门“嵌在字符串里的迷你编程语言”。 视频开宗明义:正则表达式不是某个库、某个框架的功能,而是一种跨语言通用的文本模式描述语法。你在 JavaScript 里写的 /pattern/,和 Python、Java、Go、grep、VS Code 搜索框里的写法,九成以上是同一套符号系统。这是它值得专门学一次的根本原因——学一次,处处生效。
第二层主张:核心构件只有一巴掌那么多。 视频按顺序过了一遍积木:字符组 [abc] 与取反 [^abc]、量词 * + ? {n,m}、锚点 ^ $、任意字符 .、分组 () 与"或" |,再进阶到反向引用 \1 和前瞻断言。演示时它用了 JavaScript 的 .test() 方法,现场跑一个模式去匹配字符串,返回 true/false——用最小的可运行例子让你看见“模式在吃字符串”。这个教学策略很聪明:正则的难点从来不是语法记忆,而是“拿真实输入立刻验证”的反馈循环。
第三层主张:一行正则替代三十行代码。 这是标题党式但基本诚实的卖点。视频暗示的场景每个开发者都遇到过:从日志里抽 IP、校验表单格式、批量重构变量名、解析半结构化文本。用循环+条件判断堆出来的字符串处理代码,往往又长又脆;换成一条设计良好的正则, LOC 直接塌缩一个数量级。
第四层是它没说透的隐藏主张:正则是把双刃剑。 三分钟的体量装不下这个话题——而“剑的另一面”恰恰是本文后面最值得你带走的部分:同一条正则,可以让一个服务的 CPU 在 27 分钟内烧到 100%,让半个互联网的请求集体失败。这不是思想实验,是 2019 年真实发生的事故(下文详述)。
很多人不知道,正则表达式的诞生地不是贝尔实验室,而是神经科学。1956 年,数学家 Stephen Cole Kleene 在论文《Representation of Events in Nerve Nets and Automata》中,研究 Warren McCulloch 与 Walter Pitts 提出的神经元网络模型时,提出了一套描述"神经系统里哪些事件可以发生”的代数记号——他把这类事件称为"regular events"(正则事件)。所以严格地说,正则表达式的第一代“运行环境”是大脑模型,第二代才是计算机。这个冷知识顺带解释了正则的气质:它天生是关于“模式识别”的语言,而模式识别正是神经系统的看家本领。
1968 年,贝尔实验室的 Ken Thompson 在《Communications of the ACM》上发表《Regular Expression Search Algorithm》,把 Kleene 的记号第一次变成可执行的搜索算法,并植入了他在 CTSS 上用的 QED 编辑器。这条血脉一路传下去:QED→ed→grep。grep 这个名字本身就是正则的墓志铭——g/re/p,即 ed 编辑器里“全局(global)搜索正则表达式(regular expression)并打印(print)”的命令序列。今天你在终端里敲的每一个 grep,都在调用一条 1968 年定型的技术路线。
这是整条视频背后最重要的理论知识,也是 Fireship 完全没有展开的部分。同一个正则模式,在不同引擎上跑,性能可能有天壤之别,根源在于引擎实现分两派:
2007 年,Google 工程师 Russ Cox 发表了著名的三部曲文章《Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby, ...)》,系统对比两派并指出:业界主流语言“放着线性算法不用,集体选择了会爆炸的算法”。这篇文章直接催生了 Google 的 RE2 库——一个保证线性时间的 C++ 正则引擎,曾支撑 Google Code Search;Go 语言的 regexp 标准库和 Rust 的 regex crate 都是 RE2 思想的直系后代,官方文档明确宣称不提供回溯、保证线性时间。
理论上的“指数爆炸”长什么样?2019 年 7 月 2 日,全世界见识了一次。当天 13:30(UTC)起,Cloudflare 全球边缘网络出现大面积 502 错误,大量网站无法访问,持续约 27 分钟。事后 CTO John Graham-Cumming 发布了技术复盘:一名工程师部署了一条新的 WAF(Web 应用防火墙)规则,其中一条正则含有嵌套量词结构(形如“可无限重复的组里又嵌着可无限重复的部分”)。这类模式喂给回溯型引擎时,某个恶意构造的 HTTP 请求就能触发灾难性回溯——CPU 在 combinatorial 爆炸中被烧到 100%,全球边缘节点集体瘫痪。复盘文章公称为一次“全球性停摆(global outage)”,并详细记录了从定位到回滚配置的完整时间线。这条新闻至今仍被当作 ReDoS(Regular expression Denial of Service,正则拒绝服务攻击)的教科书案例,OWASP 也为此维护着专门的 ReDoS 攻击条目与防御指南。
学术侧同样有量化证据:Virginia Tech 团队 Davis 等人在 ESEC/FSE 2017 发表的实证研究《The Impact of Regular Expression Denial of Service (ReDoS) in Practice》,大规模扫描了 npm 生态,报告了数以千计的 JavaScript 模块携带可被 ReDoS 攻击的正则——换句话说,你今天 npm install 下来的依赖树里,大概率就埋着几颗“Cloudflare 级”的小型地雷。
雅的彩蛋:正则可以判定素数。著名的 ^1?$|^(11+?)\1+$ 利用非贪婪捕获与反向引用,在“一进制”(用 11 表示 2、111 表示 3)上完成素性检验——它恰恰依赖回溯派引擎的反向引用能力,在 RE2 这类线性引擎上反而写不出来。这是“表达力换性能”最优雅的注脚。
俗的彩蛋:那句流传了二十多年的程序员圈谚语——"Some people, when confronted with a problem, think 'I know, I'll use regular expressions.' Now they have two problems."(有些人遇到问题想:我知道,用正则!于是他们有了两个问题。)通常归于 Netscape/Perl 老兵 Jamie Zawinski 在 1997 年的 Usenet 发言。它和视频的“一行抵三十行”构成一组绝妙的对冲:正省下的行数,就是负省下的可读性。
证据充分的部分。 自动机理论与回溯指数爆炸有严格的数学基础,不是经验之谈;Thompson 算法的线性性有 Cox 文章和 RE2/Go/Rust 的工程实现双重背书;Cloudflare 事故有厂商官方复盘全文,时间线、根因、修复过程全部公开,属于罕见的高透明度案例;npm 生态的 ReDoS 普遍性有同行评审论文支撑。这些是本文可以放心敲黑板的部分。
需要打折的部分。 其一,"100 秒学会”是营销话术。视频教你的是语法构件,而从“认识构件”到“写出正确、高效、可维护的正则”之间隔着大量实践——尤其嵌套量词的陷阱,恰恰是初学者最容易踩、而视频无暇提示的。其二,“一行抵三十行”要辩证看:行数塌缩的代价是可读性塌缩,团队里能看懂复杂正则的人永远少于能看懂三十行循环的人。其三,关于邮箱校验这类经典用例,社区早有共识:RFC 5322 兼容的正则长到荒谬,Stack Overflow 上围绕“用正则校验邮箱”的经典问题积累了百万级浏览量,高票答案几乎一边倒地建议——别硬校验,发一封确认邮件才是唯一可靠的验证。视频作为入门演示拿邮箱举例可以理解,照搬到生产环境则是另一回事。其四,客观地说,这条视频是 Fireship 内容漏斗的一环,节奏服务于"信息密度观感",深水区的风险提示不是它的任务——这不是贬低,而是观看这类“神课”时应有的清醒。
长期争议点。 “该不该用正则处理结构化数据(HTML/JSON)"是社区常年互怼的话题。正则派说快,解析器派说稳。主流工程判断是:一次性的日志抽取、文本清洗,正则利大于弊;任何有嵌套结构的正式解析场景,请用真正的解析器——正则的“正则”二字(regular)本身就宣告了它只擅长正则语言,而 HTML 的嵌套结构早已超出正则语言的表述能力。
启示一:把“引擎选型”纳入正则技能树。 大多数人把正则当成纯语法知识,真正的分水岭在于追问一句:“这条正则会跑在回溯型引擎还是线性型引擎上?" 在高并发、处理不可信输入的路径上(网关、防火墙、日志接入),优先选 Go regexp、Rust regex、RE2 这类线性保证的实现;如果困在 JavaScript/Python 生态,至少在上线前用最坏输入(长串重复字符+嵌套量词模式)做一次压力测试,并为匹配操作设置超时或回溯上限(如 PHP 的 pcre.backtrack_limit)。npm 生态有 safe-regex、recheck 等静态检测工具,值得进 CI。
启示二:用 80/20 法则学语法,用可视化工具建立反馈循环。 字符组、量词、锚点、分组这四类构件覆盖了九成日常需求,先吃透它们,反向引用与断言按需补课。练习时别在编辑器里盲写——regex101、regexr 这类站点能实时可视化每一步匹配过程、标出回溯热点,把正则学习从“背咒语”变成“看得见的实验”。把复杂正则当代码而非字符串来维护:开启 verbose 模式加注释、使用命名分组、为它写单元测试。
启示三:警惕“来源不可信的正则”。 Cloudflare 事故的正则是自家工程师写的,尚且酿成全球事故;而现实中风险更大的场景是用户自定义正则——比如让用户输入自己的过滤规则、搜索语法的系统。这类入口等于把 CPU 出租给了外部世界,必须叠加静态检测、超时熔断、沙箱执行三层防护。一个朴素的代码审查习惯:看到 (.*)*、(.+)+ 这类嵌套量词结构,直接打回重写。
flowchart TD
A["1956 Kleene<br>研究神经元网络提出正则事件"] --> B["1968 Ken Thompson<br>QED / ed / grep 首个工程实现"]
B --> C{"两条引擎路线"}
C -->|"回溯派 NFA"| D["Perl / PCRE / JS / Python<br>支持反向引用 表达力强"]
C -->|"自动机派 线性"| E["Thompson 算法 / RE2<br>Go regexp / Rust regex"]
D --> F["嵌套量词触发指数回溯<br>ReDoS 风险"]
F --> G["2019-07-02 Cloudflare<br>全球宕机约27分钟"]
G --> H["OWASP ReDoS 防护指南<br>safe-regex / recheck 进CI"]
B --> I["Fireship 100秒神课<br>一行正则替代三十行代码"]
I --> J["收益 表达力与效率"]
I --> K["代价 可读性与风险"]
E --> L["线性时间保障<br>高并发不可信输入首选"]
J --> M["工程正解 会用 更要会防"]
K --> M
H --> M
L --> M
本文由「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 等场景全覆盖。
