查缺补漏之正则表达式
首先要明白正则表达式可以干什么?
正则表达式是用于匹配字符串中字符组合的模式。简单的说就是比如你想知道一串数字是否是正确的手机号。就需要用到正则表达式。由于之前一直对正则表达式的知识比较薄弱,所以在此进行查缺补漏
一、创建一个正则表达式
创建一个正则表达式的方法有两种:
字面量创建;
1 | const regTest = /[a-z]/ |
使用构造函数创建
1 | const regTest = new RegExp('[a-z]') |
这里就使用第一种简单字面量的方式来熟悉正则表达式相关知识。正则表达式的匹配方法有很多例如 exex()、test()、match()等。这里主要熟悉正则的编写,方法先不做介绍。能看懂下面的匹配方法就行
1 | const helloReg = /Hello/ |
二、正则表达式修饰符
修饰符是在字面量的结尾加上的参数。或是用构造函数创建的对象第二个参数。如:new RegExp('[a-z]', i);
| 修饰符 | 描述 |
|---|---|
| i | 执行对大小写不敏感的匹配。 |
| g | 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。 |
| m | 执行多行匹配。 |
三、正则表达式中的特殊字符
断言类
表示一个匹配在某些条件下发生。断言包含先行断言、后行断言和条件表达式。
| 特殊字符 | 含义 |
|---|---|
| ^ | 匹配输入的开头。(或对后面的校验取反) |
| $ | 匹配输入的结束。 |
字符类
区分不同类型的字符,例如区分字母和数字。
| 特殊字符 | 含义 |
|---|---|
| . | 默认匹配除换行符之外的任何单个字符。例如,/.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“中的所有字母 |
量词类
量词表示要匹配的字符或表达式的数量。
| 特殊字符 | 含义 |
|---|---|
| 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“ |
括号类
| 括号 | 含义 |
|---|---|
| () | 小括号用于对字符或元字符进行分组以及表示可选择性。如(A\d){1,3}和(red|green) |
| [] | 方括号用于查找某个范围内的字符。例如[0-9]、[a-z]、[A-D] |
| {} | 大括号用于标记限定符表达式的开始。如n{1,9}匹配 X 至 Y 个 n 的序列的字符串。 |
四、实现几个常用的正则表达式
手机号
手机号的校验分为以下几个部分:
①11 位数字,不能多也不能少;得到如下/\d{11}/
② 第一位数字必须为 1,第二位为 3,4,5,6,7,8,9 中的一个;得到
1 | /^1[3-9]{1}\d{9}$/ |
③ 注意不要忘了用上^匹配开始和$匹配结尾。不然超过 11 位的也会被校验成功
身份证号
身份证号的校验分为以下几个部分:
① 地区的前两位为省级;第一位为 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 | /^[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)$/ |
当然光靠正则的校验不够完善,比如 2 月份只有 28 天的情况,或者 29 天的情况。这里没有做到控制。更完善的校验需要编写一个方法来实现。
邮箱
邮箱的校验分为以下几个部分:
① 只允许英文字母、数字、下划线、英文句号、以及中划线;([a-zA-Z0-9._-])+
②@符号;@
③ 域名:一般域名的规律为“[N 级域名.][三级域名.]二级域名.顶级域名”,比如“ qq.com ”、“ www.qq.com ”、“ mp.weixin.qq.com ”、“ 12-34.com.cn ”,分析可得域名类似“ ** .** .** .** ”组成。
1 | `**` 可表示为:([a-zA-Z0-9_-])+ |
1 | `.**` 可表示为:(.[a-zA-Z0-9_-]{2,3}) |
1 | `**.**.**.**` 得到:([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3})){1,3} |
④ 讲上述上个结合得到:
1 | /^([a-zA-Z0-9._-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3})){1,3}$/ |
强密码(必须包含大小写字母和数字的组合,长度在 8-16 之间)
强密码校验分为以下几个部分:
① 长度 8-16 位{8,16}
② 包含大小写字母和数字[a-zA-Z0-9]{8,16}
③ 确保同时含有字母和数字?
这里使用(?=.*\d)(?=.*[a-z])(?=.*[A-Z]) 来匹配当前式子同时含有大小写字母和数字。其中 (?=) 是用来预测后续的内容与当前表达式匹配。参见第三点的量词类倒数第二个。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。这里使用了三个预测先行(?=)(?=)(?=)也就是说需要同时满足三个匹配条件。
④ 最终得出结果:
1 | /(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9]{8,16}/ |




