讲解

正则表达式(regular expression,常缩写为 regex 或 regexp)是一套用来描述「文本模式」的符号体系。给定一个模式,正则引擎就能回答两类问题:这段文本里有没有符合模式的内容(校验、搜索),以及符合模式的部分具体是什么(提取、替换)。凡是需要按规则处理字符串的场合——表单校验、日志分析、批量重命名、代码搜索替换——都有它的用武之地。

正则不是某一门语言的专利,而是一套跨语言的「迷你语言」:JavaScript、Python、Java、grep、sed 都内置支持。但要注意各家的「方言」差异:语法主体相通(\d、量词、分组几乎处处一样),细节上却有出入,比如高级特性环视、命名分组的写法和兼容性并不统一。本教程的示例以 JavaScript 语法为主线(浏览器控制台就能跑),另有一章专门讲 Python 的 re 模块并对照差异。

学正则没有捷径,唯一的办法是多写多测。本教程每个示例里都带了 console.assert 断言,把「这个模式应该匹配什么、不应该匹配什么」固化成可执行的检验,你在控制台或 Node 里原样运行就能看到结果。读完本教程,你将掌握元字符、字符类、量词、锚点、分组、环视等核心概念,并能在 JavaScript 和 Python 里熟练使用。

示例

先建立直观感受:下面这个模式 \d{3}-\d{4} 表示「3 位数字、一个连字符、4 位数字」。

// 第一个正则:找出「3 位数字-4 位数字」形状的分机号
const re = /\d{3}-\d{4}/;
console.log(re.test('分机号是 123-4567')); // true
console.log(re.test('分机号是 12-3456')); // false
console.assert(re.test('分机号是 123-4567') === true);
console.assert(re.test('分机号是 12-3456') === false);
console.assert(re.test('没有任何数字') === false);

正则不止能「判断有没有」,还能把匹配到的内容取出来、替换掉:

// match:取出匹配到的片段
const found = '工号 A9527 已登记'.match(/[A-Z]\d{4}/);
console.log('匹配结果:', found[0]);
console.assert(found[0] === 'A9527');

// replace:把手机号中间四位打码(1 开头共 11 位数字)
const masked = '手机号 13812345678 已验证'.replace(/1\d{10}/, (m) => m.slice(0, 3) + '****' + m.slice(7));
console.log(masked);
console.assert(masked === '手机号 138****5678 已验证');

暂时看不懂这些符号没关系——\d、[A-Z]、{4} 这些记号正是后面章节要逐个讲的内容,这里只需记住:正则就是用符号精确描述「要什么样的文本」。

常见坑

  • 以为正则是统一标准:不同语言、不同工具的正则方言有差异,网上抄来的模式换个环境可能报错或行为不同,抄之前先确认目标引擎。
  • 想用正则解决一切:正则不擅长解析嵌套结构(HTML、JSON、括号配对),那是解析器的活儿。最佳实践一章会展开讲。
  • 只抄不理解:一个看不懂的正则比没有正则更危险——它可能在你没测过的输入上悄悄失效或误匹配。
  • 只看不动手:正则符号密度高,光看不练很快就会忘。每个示例都亲自跑一遍、改一改,观察结果怎么变。

小结

正则表达式是描述文本模式的跨语言迷你语言,能完成校验、搜索、提取、替换四类任务;各家方言大同小异,本教程以 JavaScript 为主线。下一节从最简单的字面量匹配开始。