正则表达式速查表
面向 JavaScript 方言的可搜索正则速查表:字符类、方括号集合、量词、锚点、环视、分组与标志位,每条都配有示例。
41 条正则语法,条条带示例。 在记号、说明和示例中同时筛选,找到需要的语法直接复制。内容以浏览器与 Node.js 使用的 JavaScript(ECMAScript)方言为准。
没有语法条目匹配当前筛选条件。
面向 JavaScript 方言的可搜索正则速查表:字符类、方括号集合、量词、锚点、环视、分组与标志位,每条都配有示例。
41 条正则语法,条条带示例。 在记号、说明和示例中同时筛选,找到需要的语法直接复制。内容以浏览器与 Node.js 使用的 JavaScript(ECMAScript)方言为准。
没有语法条目匹配当前筛选条件。
正则表达式天生就写得很密。^(?:\d{1,3}\.){3}\d{1,3}$ 这样一个模式,用三十来个字符就塞进了一个完整的 IPv4 校验器——自己写的时候很爽,读别人写的时候很痛苦。难点其实大多不在概念,而在于这套词汇量大、写法简短,且极容易记个半吊子。
本页就是这套词汇的查询表,按照实际构建模式的顺序组织:匹配单个字符的写法、如何自定义字符集合、如何表达「重复若干次」、在哪里加锚点、怎样分组与选择,以及哪些标志位会改变引擎行为。筛选框会同时搜索记号、说明和示例,因此输入「惰性」「boundary」或「lookbehind」都能直接跳到你记了一半的那一行。
正则表达式并不是一种统一的语言。grep、PCRE、Python、Java、Go 的 RE2 和 JavaScript 共享一个核心,但在细节上各不相同。这里列出的全部内容都以 ECMAScript 定义的 JavaScript 方言为准,因为那正是浏览器、Node.js 和绝大多数前端工具链所运行的方言。
有三处差异值得特别提醒。第一,后行断言 (?<=...) 与 (?<!...) 在现代 JavaScript 引擎中受支持,但 Go 的 RE2 和较旧版本的 Safari 并不支持,因此依赖它的模式并非处处可移植。第二,JavaScript 没有 x 详细模式标志,无法像 Python 那样把模式拆成多行并加注释;较长的模式通常改用字符串片段拼接而成。第三,JavaScript 中的 \d 与 \w 默认只覆盖 ASCII,因此 \w 不会匹配带重音的字母或中日韩字符,除非配合 u 标志改用 \p{L} 这类 Unicode 属性转义。
两个习惯能避免绝大多数正则相关的痛苦。第一是有意识地加锚点。没有锚点的模式会在字符串的任意位置寻找匹配——扫描文本时这正是你要的,但做校验时几乎从来不是。加上 ^ 和 $,就把「包含某个看起来像日期的片段」变成了「本身就是一个日期」,而这条区别背后藏着相当比例的校验缺陷。
第二是优先使用惰性量词和排除型字符类,而不是贪婪通配。经典错误是在类 HTML 文本上写 <.+>:由于 + 是贪婪的,它会一路吞到该行最后一个 >。写成 <.+?>,或者更好的 <[^>]+>,才只匹配单个标签。排除型字符类的版本还明显更快,因为引擎完全不需要回溯。
最后要留意灾难性回溯。像 (a+)+b 这样嵌套量词,可能让引擎在得出「不匹配」结论之前,先尝试指数级数量的切分方式;一旦这种模式接触用户输入,一次校验调用就变成了拒绝服务的攻击面。如果模式里有一个带量词的分组、内部又含量词,就应该重写它——通常改成「一个字符类加一个量词」就能在线性时间内完成同样的工作。而当模式长到超过一两行时,坦白讲,正确的工具往往是一个真正的解析器,而不是正则。