网站

正则表达式 | MDN

正则表达式 | 菜鸟教程

引入

处理字符串时经常需要判断格式或者提取信息,比如”这是不是手机号""这段文本里有哪些邮箱地址”。

正则表达式是一套匹配规则,用来描述字符串的模式。它能帮你判断一个字符串是否符合某种格式,也能从文本中找出所有匹配的内容。

正文

定义

正则表达式(Regular Expression)是一种用来匹配字符串模式的工具,可以用特定规则描述”什么样的字符串”。

创建正则

两种写法:

const regex1 = /hello/;
 
const regex2 = new RegExp("hello");

字面量写法 /pattern/ 更常用,RegExp 构造函数适合动态拼接模式。

标志(Flags)

写在最后一个 / 后面,控制匹配行为。

标志说明
g全局匹配,找到所有匹配项
i忽略大小写
m多行匹配,^$ 匹配每行的开头和结尾
const regex = /hello/gi;

字符类

写法说明
\d数字,等同于 [0-9]
\D非数字
\w字母、数字、下划线,等同于 [a-zA-Z0-9_]
\W非单词字符
\s空白字符(空格、Tab、换行)
\S非空白字符
.任意字符(除换行符外)
[abc]匹配 a、b 或 c
[a-z]匹配 a 到 z 之间的字符
[^abc]匹配除了 a、b、c 以外的字符
const regex = /\d{3}/;
 
console.log(regex.test("123"));
console.log(regex.test("ab"));

量词

量词说明
*0 次或多次
+1 次或多次
?0 次或 1 次
{n}恰好 n 次
{n,}至少 n 次
{n,m}n 到 m 次
const regex = /a+/;
 
console.log(regex.test("a"));
console.log(regex.test("aaa"));
console.log(regex.test(""));

量词默认是贪婪匹配,会尽量多匹配。加 ? 可以变成非贪婪匹配:

const html = "<p>hello</p>";
 
const greedy = /<.+>/;
const lazy = /<.+?>/;
 
console.log(html.match(greedy));
console.log(html.match(lazy));

边界(Anchors)

写法说明
^匹配字符串开头
$匹配字符串结尾
\b单词边界
const regex = /^\d{6}$/;
 
console.log(regex.test("123456"));
console.log(regex.test("a123456"));

分组

() 把一部分规则组合在一起,可以用 | 表示”或”。

const regex = /(hello|hi) world/;
 
console.log(regex.test("hello world"));
console.log(regex.test("hi world"));

分组还可以用来捕获匹配到的内容:

const regex = /(\d{4})-(\d{2})-(\d{2})/;
 
const result = "2024-03-15".match(regex);
 
console.log(result[0]);
console.log(result[1]);
console.log(result[2]);
console.log(result[3]);

正则方法

test()

返回布尔值,判断字符串是否匹配。

const regex = /\d+/;
 
console.log(regex.test("abc123"));
console.log(regex.test("abc"));

exec()

返回匹配结果的详细信息,没有匹配返回 null

const regex = /\d+/;
 
const result = regex.exec("abc123def");
 
console.log(result[0]);
console.log(result.index);

字符串方法配合正则

match()

返回所有匹配结果的数组。

const str = "one 1 two 2 three 3";
 
const result = str.match(/\d/g);
 
console.log(result);

replace()

替换匹配到的内容。

const str = "Hello World";
 
const result = str.replace(/world/i, "JavaScript");
 
console.log(result);

替换函数中使用分组:

const str = "2024-03-15";
 
const result = str.replace(/(\d{4})-(\d{2})-(\d{2})/, "$1年$2月$3日");
 
console.log(result);

返回第一个匹配的位置,没找到返回 -1

const str = "Hello World";
 
console.log(str.search(/world/i));

split()

按正则拆分字符串。

const str = "one,two;three four";
 
const result = str.split(/[,;\s]+/);
 
console.log(result);

常用模式

手机号

const phoneRegex = /^1[3-9]\d{9}$/;
 
console.log(phoneRegex.test("13812345678"));
console.log(phoneRegex.test("12345678901"));

邮箱

const emailRegex = /^[\w.-]+@[\w.-]+\.\w{2,}$/;
 
console.log(emailRegex.test("[email protected]"));
console.log(emailRegex.test("not-an-email"));

身份证号(18 位)

const idRegex = /^\d{17}[\dXx]$/;
 
console.log(idRegex.test("110101199001011234"));

URL

const urlRegex = /^https?:\/\/[\w.-]+\.\w{2,}/;
 
console.log(urlRegex.test("https://example.com"));
console.log(urlRegex.test("not a url"));

特性总结

方法来源返回值用途
test()正则布尔值判断是否匹配
exec()正则数组或 null获取匹配详情
match()字符串数组或 null获取所有匹配
replace()字符串新字符串替换匹配内容
search()字符串数字查找匹配位置
split()字符串数组按规则拆分

理解

正则表达式可以理解为一种字符串的筛选公式

你写下一个模式,告诉程序”我要找长什么样的字符串”,程序就按这个公式去匹配。

\d 代表”这里要一个数字”,+ 代表”前面的规则重复多次”,^$ 代表”从头到尾都要符合”。

刚开始学正则不需要背所有规则,先掌握 \d\w+*^$ 这几个最常用的,能解决大部分场景。遇到复杂规则再查就行。

引出

正则表达式经常配合 JS 字符串 的各种方法一起使用,比如 match()replace()split()

学会正则之后,做表单验证、文本处理都会方便很多。