首先要明白正则表达式可以干什么?
正则表达式是用于匹配字符串中字符组合的模式。简单的说就是比如你想知道一串数字是否是正确的手机号。就需要用到正则表达式。由于之前一直对正则表达式的知识比较薄弱,所以在此进行查缺补漏
一、创建一个正则表达式
创建一个正则表达式的方法有两种:
- 字面量创建;
const regTest = /[a-z]/
- 使用构造函数创建
const regTest = new RegExp('[a-z]');
这里就使用第一种简单字面量的方式来熟悉正则表达式相关知识。正则表达式的匹配方法有很多例如exex()、test()、match()等。这里主要熟悉正则的编写,方法先不做介绍。能看懂下面的匹配方法就行
const helloReg = /Hello/;
const str = 'Hello World';
helloReg.test(str) // true
二、正则表达式修饰符
修饰符是在字面量的结尾加上的参数。或是用构造函数创建的对象第二个参数。如:new RegExp('[a-z]', i);
修饰符 | 描述 |
---|---|
i | 执行对大小写不敏感的匹配。 |
g | 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。 |
m | 执行多行匹配。 |
三、正则表达式中的特殊字符
1.断言类
表示一个匹配在某些条件下发生。断言包含先行断言、后行断言和条件表达式。
特殊字符 | 含义 |
---|---|
^ | 匹配输入的开头。 |
$ | 匹配输入的结束。 |
2.字符类
区分不同类型的字符,例如区分字母和数字。
特殊字符 | 含义 |
---|---|
. | 默认匹配除换行符之外的任何单个字符。例如,/.n/ 将会匹配 “nay, an apple is on the tree” 中的 ‘an’ 和 ‘on’,但是不会匹配 ‘nay’。 |
\b | 匹配一个单词的边界,即匹配两边中的一边没有其他元素或者空格。例如:/123\b/匹配’123 456’中的’123’ |
\B | 匹配非单词边界,例如/\Bpple/ 匹配"apple"中的“pple” |
\d | 匹配任何数字(阿拉伯数字)。 相当于 [0-9] . 例如, /\d/ 或 /[0-9]/ 匹配 “B2is the suite number”中的“2”。 |
\D | 匹配任何非数字(阿拉伯数字)的字符。相当于[^0-9] . 例如, /\D/ or /[^0-9]/ 在 “B2 is the suite number” 中 匹配 “B”. |
\n | 匹配换行符。例如/\n/g 匹配"I am a boy. \n "中的换行符 |
\w | 匹配基本拉丁字母中的任何字母数字字符,包括下划线。相当于 [A-Za-z0-9_] . |
\W | 匹配任何不是来自基本拉丁字母的单词字符。相当于 [^A-Za-z0-9_] . |
\s | 匹配空白字符。例如/\s/g 匹配"I am a boy"中的所有空格 |
\S | 匹配非空白字符。例如/\S/g 匹配”I am a boy“中的所有字母 |
3.量词类
量词表示要匹配的字符或表达式的数量。
特殊字符 | 含义 |
---|---|
x* | 将前面的项“x”匹配0次或更多次。等价于 {0,} 例如/bo*/匹配“A ghost booooed”中的“boooo” |
x+ | 将前一项“x”匹配1次或更多次。等价于{1,} 。例如,/a+/匹配“candy”中的“a”和“caaaaaaandy”中的“a”。 |
x? | 将前面的项“x”匹配0或1次。等价于 {0,1} 。 |
x{n} | 其中“n”是一个正整数,与前一项“x”的n次匹配。例如,/a{2}/ 不匹配“candy”中的“a”,但它匹配“caandy”中的所有“a”,以及“caaandy”中的前两个“a”。 |
x{n,} | 其中,“n”是一个正整数,与前一项“x”至少匹配“n”次。例如,/a{2,}/ 不匹配“candy”中的“a”,但匹配“caandy”和“caaaaaaandy”中的所有a。 |
x{n,m} | 其中,“n”是0或一个正整数,“m”是一个正整数,且m > n至少与前一项“x”匹配,最多与“m”匹配。 |
?=n | 匹配任何其后紧接指定字符串 n 的字符串。例如/is(?= all)/g 匹配 “There is all” 中的 “is all” |
?!n | 匹配任何其后没有紧接指定字符串 n 的字符串。例如/is(?! all)/gi 匹配 “Is there all?” 中的 “Is“ |
4.括号类
括号 | 含义 |
---|---|
() | 小括号用于对字符或元字符进行分组以及表示可选择性。如(A\d){1,3}和(red|green) |
[] | 方括号用于查找某个范围内的字符。例如[0-9]、[a-z]、[A-D] |
{} | 大括号用于标记限定符表达式的开始。如n{1,9} 匹配 X 至 Y 个 n 的序列的字符串。 |
四、实现几个常用的正则表达式
1. 手机号
手机号的校验分为以下几个部分:
①11位数字,不能多也不能少;得到如下/\d{11}/
②第一位数字必须为1,第二位为3,4,5,6,7,8,9中的一个;得到
/^1[3-9]{1}\d{9}$/
③注意不要忘了用上^
匹配开始和$
匹配结尾。不然超过11位的也会被校验成功
2. 身份证号
身份证号的校验分为以下几个部分:
①地区的前两位为省级;第一位为1-9,第二位为0-9;三四位为市级,五六位为县级。得到[1-9]{1}\d{5}
②出生年月日一共8位;年份从18XX开始,到目前20XX(看到网上很多是校验到3XXX,这里以我个人的理解先校验到20XX);得到如下(18|19|20)\d{2}
。
月份01~12;((0[1-9])|(10|11|12))
。
日期01~31;((0[1-9])|1\d{1}|2\d{1}|3[01])
。
③顺序码;\d{3}
,校验码(\d|X|x)
④最后讲上面所有的检验结合得到如下:
/^[1-9]{1}\d{5}(18|19|20)\d{2}((0[1-9])|(10|11|12))((0[1-9])|1\d{1}|2\d{1}|3[01])\d{3}(\d|X|x)$/
3. 邮箱
邮箱的校验分为以下几个部分:
①只允许英文字母、数字、下划线、英文句号、以及中划线;([a-zA-Z0-9._-])+
②@符号;@
③域名:一般域名的规律为“[N级域名.][三级域名.]二级域名.顶级域名”,比如“qq.com”、“www.qq.com”、“mp.weixin.qq.com”、“12-34.com.cn”,分析可得域名类似“**
.**
.**
.**
”组成。
** 可表示为:([a-zA-Z0-9_-])+
.** 可表示为:(.[a-zA-Z0-9_-]{2,3})
**.**.**.** 得到:([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3})){1,3}
④讲上述上个结合得到:
/^([a-zA-Z0-9._-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3})){1,3}$/
// 根据特殊字符 \w 相当于 `[A-Za-z0-9_]`。于是可以用以下正则代替上行
/^[\w.-]+@[\w-]+(.[\w-]{2,3}){1,3}$/
4. 强密码(必须包含大小写字母和数字的组合,长度在8-16之间)
强密码校验分为以下几个部分:
①长度8-16位{8,16}
②包含大小写字母和数字[a-zA-Z0-9]{8,16}
③确保同时含有字母和数字?
这里使用`(?=.*\d)(?=.*[a-z])(?=.*[A-Z])` 来匹配当前式子同时含有大小写字母和数字。其中 ` (?=)` 是用来预测后续的内容与当前表达式匹配。**参见第三点的量词类倒数第二个**。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。这里使用了三个预测先行`(?=)(?=)(?=)`也就是说需要同时满足三个匹配条件。
④最终得出结果:
```js
/(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9]{8,16}/
```