git 地址
https://gitee.com/childe-jia/reg-test.git
背景
在日常开发中,我们经常会遇到使用正则表达式的场景,比如一些常见的表单校验,会让你匹配用户输入的手机号或者身份信息是否规范,这就可以用正则表达式去匹配。相信大多数人在碰到这种场景的时候都是直接去网上找,然后一顿 cv 操作就过去了,下次再遇到相同的问题时,又是重复一遍之前的操作。
正则作为一个用途比较广泛的技术,理应被我们所掌握,而不是每次都只有在需要用到的时候临时去网上查找,如果出了问题你也找不到问题出在哪。我们今天的课程就会教大家如何去使用正则表达式,不光能看懂别人写的,也可以自己去写一些常见的正则表达式。
什么是正则表达式?
-
正则表达式是用于匹配字符串中字符组合的模式。许多语言都支持正则表达式,在 JavaScript 中,正则表达式也是对象。
-
就是用来匹配字符串的规则
-
判断一个字符串中是否包含有某个字符或者某个字符串
找出字符串’000000O0000000’中是否有大写字母 O
-
判断用户输入的手机号是否合法
-
正则表达式的语法
语法
定义一个正则表达式
const 变量名 = /表达式/;
比如:
const reg = /前端/;
- test() - 用来查看正则表达式与指定的字符串是否匹配
const reg = /前端/;
reg.test("学前端,来黑马"); // true
- exec() - 查找符合规则的字符串
const reg = /前端/;
const str = "学前端,来黑马,前端工资高,就业前景好";
console.log(reg.exec(str)); // ['前端', index: 1, input: '学前端,来黑马,前端工资高,就业前景好', groups: undefined]
- replace() - 用来替换字符串中符合规则的字符
const reg = /java/;
const str = "学java,来黑马";
str.replace(reg, "前端"); // '学前端,来黑马'
- match() - 可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
const reg = /前端/g;
const str = "学前端,来黑马,前端工资高,就业前景好";
str.match(reg); // ['前端', '前端']
修饰符
修饰符约束正则执行的某些细节行为,如是否区分大小写、是否全局匹配
修饰符 | 说明 |
---|---|
i | 单词 ignore 的缩写,正则匹配时字母不区分大小写 |
g | 单词 global 的缩写,匹配所有满足正则表达式的结果 |
// i
console.log(/a/.test("A")); // false
console.log(/a/i.test("A")); // true// g
const str = "hello world";
str.replace(/o/, "_"); // hell_ world
str.replace(/o/g, "_"); // hell_ w_rld
元字符
普通字符
大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字。
元字符
是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能
比如:匹配 26 个英文字母,用普通字符表示 abcde…xyz,但是用元字符表示的话,只需要 [a-z]
-
边界符
(1)单词边界
找出某句话中的某个单词,例如:
The cat scattered his food all over the room.
想找到
cat
这个单词,但是如果只是使用/cat/
这个正则,就会同时匹配到cat
和scattered
这两处文本,这时候就可以用到单词边界\b
,它其实匹配的是能构成单词的字符(\w)和不能构成单词的字符(\W)中间的那个位置。// 这个正则就只会匹配到单词cat而不会匹配到scattered了 const reg = /\bcat\b/;
(2)字符串边界
边界符 说明 ^ 表示匹配行首的文本 $ 表示匹配行尾的文本 注意:如果^ 和 $ 在一起,表示必须是精确匹配
-
量词:表示某个模式出现的次数
量词 说明 * 重复 0 次或更多次 + 重复 1 次或更多次 ? 重复 0 次或 1 次 {n} 重复 n 次 {n,} 重复 n 次或更多次 {n,m} 重复 n 到 m 次 注意:逗号两侧不能出现空格
-
字符类
(1)[ ] 匹配字符集合
// 后面的字符串只要包含 abc 中任意一个字符 const reg1 = /[abc]/; console.log(reg1.test("andy")); // true console.log(reg1.test("baby")); // true console.log(reg1.test("cry")); // true console.log(reg1.test("dad")); // true// 使用连字符 - 表示一个范围 const reg2 = /[a-z]/; // 匹配26个英文小写字母中的任意一个 const reg3 = /[a-zA-Z]/; // 匹配26个英文字母中的任意一个,大小写都可以 const reg4 = /[0-9]/; // 匹配0-9中的数字// []里面加上^表示取反,注意要写到中括号里 const reg5 = /[^a-z]/; // 表示匹配除了26个小写字母以外的字符
(2). 匹配除换行符之外的任意单个字符
const reg = /./; // 匹配除换行符之外的任何单个字符 reg.test("aaa"); // true reg.test("123"); // true reg.test("\n"); // false
(3)预定义:指的是某些常见模式的简写方式。
预定类 说明 \d 匹配 0-9 之间的任意数字,相当于[0-9] \D 匹配 0-9 以外的任意字符,相当于[ ^0-9] \w 匹配任意的字母,数字和下划线,相当于[a-zA-Z0-9_] \W 匹配除字母,数字和下划线以外的字符,相当于[ ^a-zA-Z0-9_] \s 匹配空格(包含换行、空格、制表符等),相当于[\t\r\n\v\f] \S 匹配非空格的字符,相当于[ ^\t\r\n\v\f]
分组和分支结构
分组
我们知道/a+/
匹配连续出现的“a”,而要匹配连续出现的“ab”时,需要使用/(ab)+
,其中括号是提供分组功能,使量词+
作用于“ab”这个整体
const reg = /(ab)+/g;
const str = "abba abbb babbba";
str.replace(reg, "cd"); // 'cdba cdbb bcdbba'
分组捕获:例如将 YYYY-MM-DD 格式的日期替换成 MM/DD/YYYY
YYYY-MM-DD 的匹配模式为 /\d{4}-\d{2}-\d{2}/
,是将整个日期作为一个组(group)匹配起来。 我们把这样的叫Group0
。
这个时候,如果我们上括号/(\d{4})-(\d{2})-(\d{2})/
,那么分组就是下面的情况:
YYYY-MM-DD Group0
YYYY Group1
MM Group2
DD Group3
想要获取每个分组匹配的内容该怎么获取呢?可以通过$
符号获取,比如$1
代表YYYY
, $2
代表MM
,所以完整的代码应该如下:
const reg = /(\d{4})-(\d{2})-(\d{2})/;
const date = "2023-01-05";
console.log(reg.test(date)); // true
console.log(date.replace(reg, "$2/$3/$1")); // 01/05/2023
分支结构
分支结构类似逻辑操作中的或操作,表示匹配规则 1 或者规则 2
const reg = /(java)|(前端)/;
const str1 = "学前端,来黑马";
const str2 = "学java,也可以来黑马";
reg.test(str1); // true
reg.test(str2); // true
案例
- 密码匹配(6-16 位字母、数字或者下划线)
const reg = /^[a-zA-Z0-9_]{6,16}$/;
- 匹配 16 进制颜色值(比如:#f0f0f0, #fff)
const reg = /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/;
- 匹配 24 小时制的时间(比如:23:59,08:29)
const reg = /^([01][0-9]|[2][0-3]):[0-5][0-9]$/;
- 手机号码脱敏
// 15812345678 => 158****5678
const reg = /(^1[3-9]\d)\d{4}(\d{4})/;
const mobile = "15812345678";
console.log(reg.test(mobile)); // true
console.log(mobile.replace(reg, "$1****$2")); // 158****5678
常用的正则的工具
-
vscode 插件:any-rule
功能:支持一键生成常见的正则表达式
-
https://regexper.com/
功能:可视化自己写的正则表达式