什么是正则
正则就是一个规则,用来处理 字符串 的规则
1、正则匹配
编写一个规则,验证某个字符串是否符合这个规则,正则匹配使用的是
test
方法2、正则捕获
编写一个规则,在一个字符串中把符合规则的内容都获取到,正则捕获使用的方法:正则的
exec
方法、字符串中的split
、replace
、match
等方法都支持正则
1 | var reg = /^$/; |
正则的元字符和修饰符
任何一个正则都是由
元字符
和修饰符
组成的
修饰符
g (global):全局匹配
i (ignoreCase):忽略大小写匹配
m (multiline):多行匹配
元字符
【 量词元字符 】
+:让前面的元字符出现一次到多次
?:出现零到一次
*:出现零到多次
{n}:出现 n 次
{n,}:出现 n 到多次
{n,m}:出现 n 到 m 次
【 特殊意义的元字符 】
\:转义字符(把一个普通字符转变为有特殊意义的字符,或者把一个有意义字符转换为普通的字符)
.:出了 \n
(换行符) 以外的任意字符
\d:匹配一个 0~9
之间的数字
\D:匹配任意一个 非0~9
之间的数字(大写字母和小写字母的组合正好是反向的)
\w:匹配一个 0~9或字母或_
之间的字符
\s:匹配一个任意空白字符
\b:匹配一个边界符
x|y:匹配 x 或者 y 中的一个
[a-z]:匹配 a-z
中的任意一个字符
[^a-z]:和上面的相反,匹配任意一个 非a-z
的字符
[xyz]:匹配 x 或者 y 或者 z 中的一个字符
[^xyz]:匹配除了 xyz
以外的任意字符
():正则的小分组,匹配一个小分组(小分组可以理解为大正则中的一个小正则)
^:以某一个元字符开始
$:以某一个元字符结束
?::只匹配不捕获
?=:正向预查
?!:负向预查
……
除了以上特殊元字符和量词元字 符,其余的都叫做普通元字符:代表本身意义的元字符
参考:RegExp
元字符详解
^ $
1 | /* 匹配一个到多个数字 */ |
\
1 | var reg = /^2.3$/; |
x|y
1 | var reg = /^18|19$/; |
():正则中的分组,也可以理解为一个大正则中的一个正则(包起来的部分是一个整体);在正则中我们可以使用小括号 改变一些默认的优先级
小分组还有第二个作用: 分组引用
小分组的第三个作用:分组捕获
1 | /* |
[]
[xyz]、【^xyz】、[a-z]、【^a-z】
1 | // \w:数字字母下划线中的任意一个字符 |
常用的正则表达式编写
验证是否为有效数字
1 | /* |
验证手机号码
1 | // 11 位数字, 以 1 开头 |
匹配用户名:真实姓名
1 | // /^[\u4E00-\u9FA5]$/; 匹配中文汉字的正则 |
匹配邮箱
1 | var reg = /^\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/; |
匹配身份证号码
1 | /* |
正则捕获
把当前字符串中符合正则的字符捕获到
RegExp.prototype:
exev
实现正则捕获的方法
1 | var str = '新年快乐2018猪事顺利2019'; |
正则捕获存在懒惰性
执行一次 exec 捕获到第一个符合规则的内容,第二次执行 exec ,捕获到的依然是第一个匹配的内容,后面匹配的内容不管执行多少次 exec 都无法捕获到
解决正则捕获的懒惰性:在正则的末尾加修饰符 g (表示全局匹配)
1 | // 正则为什么会存在懒惰性? |
exec 有自己的局限性:执行一次 exec 只能捕获到一个和正则匹配的结果(即使加了修饰符g),如果需要都捕获到,我们需要执行 N 次 exec 方法才可以
我们可以封装一个 myExecAll 方法,执行一次这个方法,可以把当前正则匹配到的全部内容都捕获到
1 | RegExp.prototype.myExecAll = function myExecAll () { |
使用字符串 match 方法实现捕获
1 | var reg = /\d+/g; |
使用字符串 match 捕获:
1、如果正则加了修饰符 g,执行一次 match 会把所有正则匹配的内容捕获到
2、如果没有加修饰符 g,执行一次 match 只能把第一个匹配的结果捕获到
局限性:在加了修饰符 g 的情况下,执行 match 方法只能把大正则匹配到的内容捕获到,对于小分组捕获的内容方法给其自动忽略了。
1 | // 需求: 把 {n} 整体捕获到,而且还要把括号中的数字也获取到 |
使用 test 方法实现正则捕获
不管是正则的匹配还是正则的捕获,在处理时候的原理是没有区别的:从字符串的第一个字符向后查找,找到符合正则规则的字符,如果可以找到,说明正则和字符串匹配( test 检测返回 true;exec 捕获返回捕获的内容),如果找到末尾都没有匹配的,说明正则和字符串不匹配 ( test 检测返回 false;exec 捕获返回 null)
如果正则设置了修饰符 g,不管使用 test 还是 exec 中的任何方法,都会修改 lastIndex 值(下一次查找是基于上一次匹配结果的末尾开始查找的)
1 | var reg = /\{(\d+)\}/g; |
使用 test 不仅可以找到匹配的内容,也能像 exec 一样把找到的内容获取到
test 返回的结果是 true/false,所以靠返回结果肯定不行
1 | /* test 实现捕获 */ |
正则只匹配不捕获的处理
字符串中常用的支持正则的方法:
match
、split
、replace
……
1 | var str = 'name=张三&age=20&lx=student'; |
replace 实现正则捕获的原理
replace:字符串中原有字符的替换
str.replace(old,new)
1 | var str = '新年快乐2018新年快乐2019'; |
replace 一般都是和正则搭配在一起使用的
1 | var str = '新年快乐2018新年快乐2019'; |
replace 原理:
1、当 replace 方法执行,第一项传递一个正则
正则不加 g:把当前字符串中第一个和正则匹配的结果捕获到,替换成新的字符
正则加 g:把当前字符串中所有和正则匹配的内容都分别捕获到,而且每一次捕获,都会把当前捕获的内容替换为新字符
2、当 replace 方法执行,第二个参数传递的是一个函数(回调函数)
首先用正则在字符串中进行查找匹配,匹配到一个符合规则的,就把传递的函数执行一次
不仅执行这个函数,而且还把正则本次捕获的结果(和执行 exec 捕获的结果一样:数组、大正则匹配、小分组匹配 都有) 当做实参传递给这个函数(这样就可以在函数中获取这些值:而这些值就是正则每一次捕获的结果)
1 | var str = 'my name is {0},i am {1} years old,i can {2}!'; |
单词首字母大写
1 | /* 单词首字母大写 */ |
时间字符串格式化
1 | var str = '2019-01-01 13:28:32'; |
去除字符串首尾空格
1 | var str = ' 去除首位空格, 去除末尾空格 '; |
URL地址栏问号传参值的解析
1 | String.prototype.myQueryURLParameter = function myQueryURLParameter (){ |
创建正则两种方式的区别
1 | // 字面量方式 |