『Regular Expression』 RegExp Cheat Sheet

『正则表达式』 正则表达式速查手册

Posted by Coekjan on February 11, 2021

本文提供的速查参考自 JavaScript: The Definitive Guide , 因此本文提供的语法仅是正则表达式语法子集. 虽然语法有所删减, 但是已经足够应付基本的字符串识别与替换.

本文部分例子来源于 JavaScript: The Definitive Guide , 图示来源于 RegExper .

直接量字符

字符 匹配
字母与数字字符 自身
\o \u0000 NULL字符
\t \u0009 水平制表符
\n \u000A 换行符
\v \u000B 垂直制表符
\f \u000C 换页符
\r \u000D 回车符
\xnn 由十六进制数nn指定的拉丁字符
\uxxxx 由十六进制数xxxx指定的Unicode字符
\cX 控制字符^X

正则表达式中的特殊字符: ^ $ . * + ? = : | \ / ( ) [ ] { }, 若需要匹配这些字符, 则应该在其前面增加\转义.

若不记得哪些标点需要转义, 可以在每个标点前都增加 \ .

字符类

字符 匹配 示例
[...] 方括号内的任意字符 [abc]与’a’, ‘b’, ‘c’都匹配
[^...] 不在方括号内的任意字符 [^abc]与除’a’, ‘b’, ‘c’外的其他字符都匹配
. 除换行符和其他Unicode行终止符外的任意字符  
\w 等价于[a-zA-Z0-9]  
\W 等价于[^a-zA-Z0-9]  
\d 等价于[0-9]  
\D 等价于[^0-9]  
\s 任何Unicode空白符  
\S 任何非Unicode空白符的字符  
[\b] 退格符(特例)  

这些字符类也可以组合使用, 如: [\s\d]匹配任意空白符数字.

重复

字符 含义
{n,m} 匹配前一项至少n次, 最多m次
{n,} 匹配前一项至少n次
{n} 匹配前一项n次
? 等价于{0,1}
+ 等价于{1,}
* 等价于{0,}

下面通过例子具体说明:

例子 含义 图示
\d{2,4} 2~4个数字
\w{3}\d? 3个字母与0~1个数字
\s+java\s+ 前后带有一个或多个空格的字符串”java”
[^(]* 零个或多个非左圆括号的字符

非贪婪重复

若需要在匹配成功尽可能早的前提下尽可能少匹配字符, 只需引入贪婪匹配标志?.

例如: 对于字符串”aaaa”, 正则表达式a+匹配了全串, 而非贪婪的a+?只匹配第一个’a’; 对于字符串”aaab”, 正则表达式a+b匹配了全串, 非贪婪匹配下的a+?b, 为尽可能早地正确匹配, 也只能匹配全串.

选择, 分组和引用

字符 含义 备注
| 选择, 匹配的是该符号左边或右边的子表达式  
(...) 组合, 将几个项组合为一个单元, 这个单元可以通过重复字符进行修饰, 而且记忆这个组合相匹配的字符串以供此后的引用使用  
(?:...) (...)相似, 只是不记忆这个组合匹配的字符  
\m 和第m个分组第一次匹配的字符相匹配, 组是圆括号中的子表达式, 组索引是从左到右括号数, (?:形式的分组不匹配 编号从1开始编号, 引用不能处于[...]中: 即[\1]这样的写法是非法的

下面的正则表达式利用这三个特性检测字符串左右是否使用了同一种引号: (['"])[^'"]*\1

指定匹配位置(锚字符)

字符 含义 示例
^ 匹配字符串开头 ^a 只与字符串开头的’a’匹配
$ 匹配字符串解为 a$ 只与字符串结尾的’a’匹配
\b 匹配单词边界 \b 与”Java Script”中的’J’与’S’匹配
\B 匹配非单词边界的位置  
reg(?=exp) 零宽正向先行断言: 串需要匹配reg且该串后面的字符匹配exp Java(?=:)与”Java:nice”中的”Java”匹配, 而与”JavaScript”中的”Java”不匹配
reg(?!exp) 零宽负向先行断言: 串需要匹配reg且该串后面的字符不匹配exp Java(?!:)与”Java:nice”中的”Java”不匹配, 而与”JavaScript”中的”Java”匹配

实质上正则表达式的语法中还包含零宽正向后发断言零宽负向后发断言, 但JavaScript并不支持这两种匹配, 所以本文并不提及.

修饰符

修饰符 含义
i 忽略大小写
g 全局匹配: 找到所有匹配, 而不是找到一个就停止
m 多行匹配: ^匹配行开头, $匹配行结尾

JavaScript中的正则替换

下面以一个简单的场景为例, 讲述正则表达式做替换的方式.

若有文本: JavaScript is the best language! , 你需要在每个单词前后都添加引号. 可以进行如下操作:

编写正则表达式(\w+)匹配单词, 分组并记忆. 随后使用String对象的replace函数进行替换:

1
2
3
var text = 'JavaScript is the best language!';
text = text.replace(/(\w+)/g, '"$1"');
console.log(text); // => "JavaScript" "is" "the" "best" "language"!

其中$1就是被匹配的第一个子串.

事实上, VSCode 的搜索功能 ctrl+F / cmd+F 也支持正则表达式, 其替换方式与上述方法一致.