本文简单介绍正则的一般使用场景,让大家对正则有初步的认识以及初步的使用。
1. 什么是正则?
正则表达式英文全称regular expression,直译就是有规律的表达式。我们用这个表示式在字符串中匹配符合其规则的字符,例如:在一段文字中你想找到所有的手机号码,那么就需要用一个规则(11个数字且首位数字应该是1)来匹配手机号,而这个规则就可以用正则(下文正则表达式都简写为正则)表示。
2. 如何在JS中创建正则
JS为我们提供了正则的内置对象,可以通过字面量和new 构造函数两种方式创建。
2.1 使用构造函数
基础用法
let reg = new RegExp('123'); // 创建了一个可以匹配字符串123的正则
进阶用法
传入变量,动态匹配
let reg = new RegExp(`${key}=\\d`);
// key是变量 \d表示数字,是正则里面的元字符(就是正则里面有特殊含义的字符,下文会说到) ,\d前面的\是转义字符,在字符串中对后面的符号进行转义(如不了解可搜索查找:字符串转义字符的使用)
2.2 使用字面量
let reg = /\d/; // 使用两个斜线//将需要匹配的规则写入
好了,以上就是创建正则的方法,是不是很简单,下面我们开始直接使用吧,在使用中会具体说明相关概念知识。
3. 正则的使用
3.1 如何利用正则去检测字符串是否符合一个设定规则呢?
在前端或者后端开发中,我们通常会对用户填写的内容进行校验,判断用户输入的内容是否有效,比如:表单中用户填写了一个手机号,此时要校验用户手机号是否有效(暂不讨论真实性),这时使用正则是一种很方便快速的方法,那我们怎么去做呢?
- 首先我们先写出一个可以匹配手机号的正则
基本规则 首位数字是1,第二位是1-9任意一个,后面9位每位可以是0-9任意一个
let reg = /1[1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/;
// []表示一个字符集合,中间的字符可以用-来连接,[1-9]就表示从数字1到数字9中的任意一个
此时这个正则可以实现我们的目的,但是这样写太长了,看起来很不美观,我们能不能把重复的部分简写呢?当然可以。正则为我们提供了特殊字符来实现。
let reg = /1[1-9]\d{9}/;
// \d 表示数字集合,也就是0-9,后面的{9}表示需要重复9次
在正则中还有很多这种特殊字符,不推荐大家刻意去记忆,而是有需要的时候查阅,使用次数多了自然会记忆,此篇也不会列举出所有的特殊字符。这里对于\d,\D,\w,\W等提供了一个小的记忆技巧,大写字母都带有非的含义,例如:\d 是数字,d是digital数字英文的缩写,\D表示非数字。
说了这么多,我们正式开始试验如何检测吧~
let reg = /1[1-9]\d{9}/;
reg.test('13773459090'); // true
reg.test('1377345909'); // false
reg.test('10773459090'); // false
使用正则原型上的test函数,将字符串传入,函数返回一个Boolean值,true通过,false不通过。
在线测试工具:https://goregex.cn/
总结:要使用正则去检测字符串是否符合某个规则,首先创建一个正则,然后将待检测的字符串传入test函数,根据函数返回的Boolean值判断。
3.2 如何使用正则替换字符串中的一段字符?
首先大家肯定知道字符串有个替换字符的函数replace,它的第一个参数可以传入一个正则。
let str = "name=zhangsan";
我们定义了一个字符串变量,想将name=
后面的zhangsan
替换,怎么做呢?
思路是这样的,我们要考虑通用性,就是name=
看为一个不变的值,后面的zhangsan
看作是一个变化的值,我们的规则应该是匹配name=一段字符
,然后把一段字符
替换成我们想要的,代码如下:
let reg = /name=.*/;
// .表示任意字符 *表示任意个数 它们是特殊符号
我们先检验一下这个正则是否正确,同样使用test方法
let reg = /name=.*/;
reg.test('name=zhangsan'); // true
接下来我们使用replace方法替换
let str = "name=zhangsan";
let reg = /name=.*/;
str.replace(reg,'lisi'); // lisi
这时会发现整个字符串都被替换了。是的,因为我们会匹配到整个name=zhangsan
然后把它们都替换,但现在我们只需要替换后面的,怎么办?
我们有两种方式:
- 使用零宽断言
let reg = /(?<=name=).*/;
let str = "name=zhangsan";
str.replace(reg,'lisi'); // name=lisi
我们使用一个括号把name=
包住,然后在前面加上?<=
表示查找前面是name=
的字符串,括号里面的内容相当于只是匹配说明,真正被匹配到的是前面是name=
的.*
,所以替换只替换了zhangsan
。
零宽断言共四种,这里不做详述,请自行查阅。
- 使用正则分组
let reg = /(name=)(.*)/;
let str = "name=zhangsan";
str.replace(reg,'$1lisi'); // name=lisi
在正则中使用()
可以将字符串进行分组,这里我们使用了两个()
,所以分成了两组,在使用replace替换时,$1
表示第一组,即name=
,替换结果就显而易见了。
同时,replace方法的第二个参数还可以是一个函数,这里我们也可以这样修改:
let reg = /(name=)(.*)/;
let str = "name=zhangsan";
str.replace(reg, function(match, p1, p2){
return p1 + 'lisi';
}); // name=lisi
match
表示匹配到的字符,p1
表示匹配到的第一组,p2
表示匹配到的第二组,函数返回的结果作为替换字符。
总结:使用正则去替换字符,首先写出符合替换规则的正则,然后检验这个正则是否正确。如果只需要替换匹配字符中的某段字符,可以通过分组或者断言处理。
3.3 如何使用正则获取字符串的一段字符?
在开头我们说到,一段字符串中含有手机号,我们知道怎么匹配了,但是怎么获取呢?很简单,使用字符串的match方法。
let str = '我的手机号是:19019901010';
let reg = /1[1-9]\d{9}/;
str.match(reg);
// 返回一个数组
// ['19019901010', index: 7, input: '我的手机号是:19019901010', groups: undefined]
// index 0 就是匹配到的手机号
str.match(reg)[0]; // 19019901010
4. 总结
通过以上介绍,你应该知道如何使用正则了,只是还有很多概念知识需要补充。例如正则的一些特殊字符,正则的标志符号i,g,m
,贪婪模式等等,这些可以在后续使用正则的途中学习。路漫漫其修远兮,吾将上下而求索,与君共勉~
ps:文中若有错误欢迎大佬指出