什么是正则
正则是一种搜索和替换字符串的一种强大的工具,正则表达式(可叫做‘regexp’或者‘reg'),其中包含了
模式
和修饰符
怎么创建正则和基本使用
创建正则表达式对象有两种语法, 一种是通过构造函数,new操作符创建,它允许从字符串中动态地构造模式, 当正则表达式会改变时,或者事先不知道什么模式,就可以使用构造函数来创建
let reg = new RegExp('冰冰')// 创建正则 第一个''里面是条件
console.log('我的心是王冰冰的'.search(reg))// 5 返回冰冰的下标
另一种是字面量的方法,通过斜杠‘/’创建,斜杠‘/’会告诉js我们正在创建一个正则, 当我们知道用什么模式,并且不会改变时,可以采用字面量的方法创建
let reg=/冰冰/ // 创建正则,'/条件/'斜杆中间放置的是条件
console.log('我的心是王冰冰的'.search(reg)) //5 返回冰冰的下标
特殊字符 字符类
上面的两个简单的小🌰是精准的匹配,我们知道是谁,可以创建,但是有些时候,我们匹配的是一个不确定的字符但是知道是什么类型的时候怎么办,比如我们来寻找冰冰的手机号,'王冰冰的手机号是:18888888888',这时候我要获取'18888888888',这个时候就该特殊字符出马了,我们知道手机号是数字0-9,那么我们就可以用\d
来获取数字了,
let reg=/\d/ // 创建正则,
console.log('王冰冰的手机号是:18888888888'.match(reg))
//["1", index: 9, input: "王冰冰的手机号是:18888888888", groups: undefined]
// 我们看到第一项输出['1'] 这个是我们的匹配的结果
// index 代表结果的下标
// input 代表我们输入的是什么
// groups 代表组的名称
但是呢,这时候我们发现了为嘛结果只有一个"1",这不是我们想要的啊,'18888888888'
才是我们要的,别急我们\d是获取一个,我们要获取多个只需\d+就可以啦
let reg=/\d+/ // 创建正则,
console.log('王冰冰的手机号是:18888888888'.match(reg))
// ["18888888888", index: 9, input: "王冰冰的手机号是:18888888888", groups: undefined]
特殊字符 | 作用 |
---|---|
d | 匹配0-9的数字等价于[0-9] |
D | 匹配一个非数字字符 |
w | 匹配一个单字字符(字母、数字、下划线)等价于[a-zA-Z0-9_] |
W | 匹配一个非单字字符除了(字母、数字、下划线等价于)[^a-zA-Z0-9_] |
s | 匹配一个空白字符,包括空格、制表符、换页符、换行符 |
S | 匹配一个非空白字符 |
\ | 在非特殊字符之前的反斜杠表示下一个字符是特殊字符,不能按照字面理解,在不是特殊字符前表示是转义字符 \\ 表示是一个\ |
表示匹配输入的开始,/^A/ 并不会匹配 "an A" 中的 'A',但是会匹配 "An E" 中的 'A'。 | |
$ | 表示匹配输入的结束,/t$/ 并不会匹配 "eater" 中的 't',但是会匹配 "eat" 中的 't'。 |
* | 匹配前一个表达式的0次或多次 |
+ | 匹配前一个表达式的1次或多次 |
? | 匹配前一个表达式的0次或1次,/e?le?/ 匹配 "angel" 中的 'el'、"angle" 中的 'le' 以及 "oslo' 中的 'l',如果紧跟在任何量词 、 +、? 或 {} 的后面*,将会使量词变为非贪婪**(匹配尽量少的字符),和缺省使用的贪婪模式(匹配尽可能多的字符)正好相反。例如,对 "123abc" 使用 /\d+/ 将会匹配 "123",而使用 /\d+?/ 则只会匹配到 "1" |
. | 匹配除了换行符以外的所有的单个字符 |
let reg=/^a?\d+$/ // 创建正则,可以以字母a开头,以数字结尾
console.log('a18888888888'.match(reg))
// ["a18888888888", index:0, input: "a18888888888", groups: undefined]
console.log('18888888888'.match(reg))
// ["18888888888", index: 0, input: "18888888888", groups: undefined]
// 匹配一个qq邮箱
let email = '199999999@qq.com'
let reg = /^\d+@\w+\.com$/;
console.log(email.match(reg));// ["199999999@qq.com"]
特殊字符 符号类
在上面的qq邮箱示例中,如果不是com结尾而是cn结尾的呢,这时候该怎么匹配,这时可以用|
表示或者
// 匹配一个qq邮箱
let email = "199999999@qq.com";
let email2 = "199999999@qq.cn";
let email3 = "199999999@qq.com.cn";
let reg = /^\d+@\w+(\.\w+)+\1?/;
let reg1 = /^\d+@\w+\.(com|cn)$/;
console.log(email.match(reg1)); // ["199999999@qq.com", ".com"]
console.log(email2.match(reg)); // ["199999999@qq.cn", ".cn"]
console.log(email3.match(reg)); // ["199999999@qq.com.cn", ".cn"]
特殊字符 | 作用 |
---|---|
| | x|y 匹配‘x’或者‘y’。 |
() | (x)捕获括号 它会匹配 'x' 并且记住匹配项,在/(f)(b)\1\2/中\1表示f,\2表示b,在正则表达式替换中可以使用$1来表示原字符串 |
{n} | n是一个正整数,匹配前一个字符出现了几次 |
{n,} | n是一个正整数,匹配前一个字符最少出现了几次 |
{n,m} | n 和 m 都是整数。匹配前面的字符至少n次,最多m次。如果 n 或者 m 的值是0, 这个值被忽略 |
[xyz] | 字符的集合,匹配[]中的任意一项,可以用- 来选一个范围[0-9] |
[^xyz] | 字符的集合,它匹配任何没有包含在方括号中的字符 |
// 匹配一个手机号,宽松超级 13,15,17,18开头的十一位数字
let tel = "18787875678";
let tel1 = "12787875678";
let reg = /^1[3,5,7,8]\d{9}$/;
console.log(tel.match(reg)); //["18787875678"]
console.log(tel1.match(reg)); //null
// 匹配一个座机号 前面四位数字-链接 后面跟着7到8位数字
let tel = "0100-89087678";
let tel1 = "010-89087678";
let reg = /^\d{3,4}-\d{7,8}$/;
console.log(tel.match(reg)); //["0100-89087678"]
console.log(tel1.match(reg)); //["010-89087678"]
方法
上面我们一直用的是match方法,它返回一个数组,在未匹配到时会返回 null。其实还有其它的方法
方法 | 描述 |
---|---|
exec | 执行查找匹配的RegExp方法,它返回一个数组(未匹配到则返回 null)。 |
test | 一个在字符串中测试是否匹配的RegExp方法,它返回 true 或 false。 |
match | 一个在字符串中执行查找匹配的String方法,它返回一个数组,在未匹配到时会返回 null。 |
matchAll | 一个在字符串中执行查找所有匹配的String方法,它返回一个迭代器(iterator |
search | 一个在字符串中测试匹配的String方法,返回匹配的位置,没有则返回-1 |
replace | 一个在字符串中执行查找匹配的String方法,并且使用替换字符替换匹配的 |
split | 一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的 String 方法 |
let tel = "0100-89087678";
let tel1 = "010-89087678";
let reg = /^\d{3,4}-\d{7,8}$/;
console.log(reg.exec(tel1)); // ["0100-89087678"]
console.log(reg.test(tel)); //true
console.log(tel.match(reg)); // ["0100-89087678"]
console.log(tel.search(reg)); //0
console.log(
tel.replace(reg, function () {
return "*".repeat(10);
})
); //**********
高级搜索
正则表达式有六个可选参数 (flags
) 允许全局和不分大小写搜索等。这些参数既可以单独使用也能以任意顺序一起使用, 并且被包含在正则表达式实例中。
方法 | 描述 |
---|---|
g | 全局搜索 |
i | 不区分大小写 |
m | 多行匹配 |
s | 允许.匹配换行符 |
u | 使用unicode码的模式进行匹配。 |
y | 执行“粘性(sticky )”搜索,匹配从目标字符串的当前位置开始 |
let str = "This this this";
let reg1 = /t/i; // 匹配t不区分大小写
let reg2 = /t/g; // 全局匹配t
let reg3 = /t/gi; // 全局匹配t不区分大小写
console.log(str.match(reg1)); // ['T']
console.log(str.match(reg2)); // ["t", "t"]
console.log(str.match(reg3)); // ["T", "t", "t"]
断言查找
方法 | 描述 |
---|---|
x(?=y) | 匹配'x'仅仅当后面跟着‘y’,这种叫做先行断言 |
(?<=x)y | 匹配'x'仅仅当前面有‘y’,这种叫做后行断言 |
x(?!y) | 匹配'x'仅仅当后面不跟着‘y’,这种叫做正向否定查找 |
(?<!x)y | 匹配'x'仅仅当前面没有‘y’,这种叫做反向否定查找 |
// 隐藏手机号
let tel = "18787875678";
let reg = /(?<=\w{3})\w+(?=\w{4})/;
tel.replace(reg, () => {
return "*".repeat(4);
});
// "187****5678"