前言:正则表达式是真的不容易搞懂,有时查完各个字符的含义也还是会是一脸懵,但是入门还是很容易的,这里就简单学习一下正则表达式。
1.正则表达式是什么?
规则表达式(Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来匹配,检索和替换那些符合某个模式(规则)的文本等。
简单来说就是代表了一个规则,通过这个规则可以匹配字符串。
2.正则表达式的基础语法
' . ' 点表示的是可以匹配除了(\n)换行符以外的任意一个字符(数字,字母,特殊字符)
' [ ] ' 方括号表示匹配一个范围,一个集合
比如:
- [0-9] 表示的是0-9之间的任意一个数字
- [a-z] 表示的是所有的小写字母中的任意一个
- [A-Z] 表示所有的大写字母中的任意一个
- [a-zA-Z] 表示所有的字母中任意一个
- [0-9a-zA-Z] 表示所有字母和数字中的任意一个
' | ' 表示的是或者
[0-9] | [a-z] : 要么是一个0-9之间的数字,要么是一个小写字母
' ( ) ' 表示分组,提升优先级(优先计算括号内,多组括号就从左到右开始)
' * ' 表示前面的表达式出现了0次到多次
[a-z][0-9]* : 一个小写字母后有数字0-多个 比如fgh34444或者hdd
' + ' 表示的是前面的表达式出现了1次到多次,也就是至少出现一次
[a-z][9]+ :一个小写字母后至少有一个9或者多个9 比如hdch8777 就不匹配,hsb9 √
' ? ' 表示前面的表达式出现了0次到1次,最少0次,最多1次
[4][a-z]? : "1234be"
'{ }' 限定前面表达式出现的次数
比如:
- {0,} 表示前面表达式出现了0次到多次,和 * 一样
- {1,} 表示前面表达式出现了1次到多次,和 + 一样
- {0,1} 表示前面表达式出现了** 0次到1次**,和 ? 一样
- {5,10} 表示前面表达式出现了5-10次
- {5} 表示前面的表达式出现了5次
' ^ ' 表示以什么开始 或者取非(反)
比如:
- ^[0-9] **以什么开始 **表示匹配的字符串要以数字开头
- [^0-9]取反,也就是说匹配的字符串要是非数字
- [^0-9a-zA-Z_] 取反,就是取特殊符号
' 就是必须以数字结尾)
^和$ 相当于严格模式
^[a-z][0-9]$ 必须以小写字母开头,以数字结尾
cdsjb678✘ b5✔
\d 数字中的任一个,相当于[0-9]
\D 非数字的任一个, 相当于[^0-9]
\s 空白符中任意一个
\S 非空白符
\w 非特殊符号 相当于[0-9a-zA-Z_]
\W 特殊符号 相当于 [^0-9a-zA-Z_]
\b 单词边界
3.正则表达式小案例
匹配座机: 比如0531-88284888 一般都是3/4位+-+7/8位
**\d{3,4}[-]\d{7,8} **(即随机数字中的一位出现3-4次,紧跟着-,然后就是数字出现7-8次)
匹配邮箱:比如[email protected]
分析电子邮件组成一般为
@ . yourname:任意英文字母(a-z/A-Z)、数字(0-9)、下划线()、英文句点(.)、连字符(-),长度大于 0。----------->[0-9a-zA-Z.-]+
domain:任意英文字母(a-z/A-Z)、数字(0-9)、下划线()、英文句点(.)、连字符(-),长度大于 0。------------>[@][0-9a-zA-Z.-]+
extension:任意英文字母(a-z/A-Z),长度大于0
optional-extension:
"."
开头,后面跟任意英文字母(a-z/A-Z),可有可无上面两部分即域名部分,一般域名有一级二级之分,所以是 . 字母任意一位出现1-多次,再利用括号分组,这一组出现一次即一级域名,出现两次即二级域名。 -------------->([.][a-zA-Z]+){1,2}
最终:[0-9a-zA-Z_.-]+[@][0-9a-zA-Z_.-]+([.][a-zA-Z]+){1,2}
4.RegExp 对象的简单使用
①创建RegExp对象和test方法
//通过构造函数的方式创建Regexp对象
var reg = new RegExp(/\d{5}/) //匹配5个数字
reg.test('asjhdkj234454') //返回true
//通过字面量的方式创建Regexp对象
var reg = /\d{5}/
reg.test('dddddddd') //返回false
[图片上传失败...(image-d8706d-1593597998298)]
test() 方法用于检测一个字符串是否匹配某个模式,如果字符串中含有匹配的文本,则返回 true,否则返回 false。
②提取一个字符串内所有数字
比如有这样的一串字符串‘小红学号:172638,小兰学号:237918,小王学号:617289’,我想要将其中所有数字提取出来。
[图片上传失败...(image-bce67c-1593597998298)]
match()是字符串的方法,传入正则表达式,返回数组
g : 在正则表达式中表示全局匹配,这里就是将匹配的3组都提取出来了
③ i :在正则表达式里忽略大小写
[图片上传失败...(image-3e636-1593597998298)]
利用字符串的replace方法替换了所有的h
④$2
$1
等等: 提取某一组
const str = "2018-06-18"
const array = str..match(/(\d{4})[-](\d{2})[-](\d{2})/g)
console.log(RegExp.$3) //18
⑤正则表达式exec方法
一个在字符串中执行查找匹配的RegExp方法,返回一个数组,未匹配返回null
⑥正则表达式match方法
一个在字符串中执行查找匹配的String方法,返回一个数组,未匹配则返回null
⑦exec方法和match方法的区别
- exec是正则表达式的方法,而不是字符串的方法,它的参数才是字符串,如下所示:
var reg = new RegExp( "abc")
var str = "3abc4,5abc6"
reg.exec(str );
2. match是字符串执行匹配正则表达式规则的方法,他的参数是正则表达,如
var reg = new RegExp("abc")
var str = "3abc4,5abc6"
str.match(reg);
3. exec和match返回的都是数组(正则表达式无子表达式,并且定义为非全局匹配)
- 如果exec执行的正则表达式没有子表达式(小括号内的内容,如/abc(\s)/中的(\s) ),如果有匹配,就返回第一个匹配的字符串内容,此时的数组仅有一个元素,如果没有匹配返回null;
var reg = new RegExp("abc")
var str = "3abc4,5abc6"
alert(reg.exec(str));
alert(str.match(reg));
- 执行如上代码,你会发现两者内容均为一样:abc,
4. 如果定义正则表达对象为全局匹配如(正则表达式无子表达式,并且定义为全局匹配)
var reg = new RegExp("abc","g")
var str = "3abc4,5abc6"
alert(reg.exec(str));
alert(str.match(reg));
- 则 为abc和abc,abc;因为match执行了全局匹配查询;而exec如果没有子表达式只会找到一个匹配的即返回。
5. 当表示中含有子表达式的情况(正则表达式有子表达式,并且定义为非全局匹配):
var reg = new RegExp("a(bc)")
var str = "3abc4,5abc6"
alert(reg.exec(str));
alert(str.match(reg));
- 你会发现两者执行的结果都是:abc,bc;
6. 当如果正则表达式对象定义为全局匹配(正则表达式有子表达式,并且定义为全局匹配)
var reg = new RegExp("a(bc)","g")
var str = "3abc4,5abc6"
alert(reg.exec(str));
alert(str.match(reg));
- 则两者返回的结果是abc,bc和abc,abc,
总结
- 当正则表达式无子表达式,并且定义为非全局匹配时,exec和match执行的结果是一样,均返回第一个匹配的字符串内容;
- 当正则表达式无子表达式,并且定义为全局匹配时,exec和match执行,做存在多处匹配内容,则match返回的是多个元素数组;
- 当正则表达式有子表示时,并且定义为非全局匹配,exec和match执行的结果是一样如上边的第5种情况;
- 当正则表达式有子表示时,并且定义为全局匹配,exec和match执行的结果不一样,此时match将忽略子表达式,只查找全匹配正则表达式并返回所有内容,如上第6种情况;