正则表达式主要还是知识点多而杂,看过很容易忘,所以,看完知识点及时练习很重要。
首先,掌握一些常用的元字符:
值得一说的是\b\B表示边界,可以在匹配结束时使用。
其次是掌握必要的量词意义:
然后我们了解一下分支与字符集的概念。
类似[abc]的,就是一个字符集,表示匹配方括号里面的一个字符。这里[abc] == [a-c]
类似(a, b, c)用( )包住的,就叫分支,当然如果没有括号阔起来也可以,但一般情况下都会用()阔起来,更直观。分支跟字符集有什么不同呢?比如/(ax|by|cz)/可以匹配 ax或者by或者cz,但如果你用字符集就办不到。
到这里,就初步掌握正则表达式,简单的已经能写出来了。
分组和引用
用正则匹配到的字符,有时候我们不需要替换,而是要利用,这时候就要用到分组,可以帮组我们很快达到某些目的,比如将2019-03-12变成03/12/2019。
我们看下分组例子:
1
2
3
4
|
let regex = /(\d{4})-(\d{2})-(\d{2})/;
let string = "2019-03-12";
console.log( string.match(regex) );
// should output: ["2019-03-12", "2019", "03", "12", index: 0, input: "2019-03-12"]
|
除了用match方法返回数组,我们还可以用全局属性$1至$9来匹配分组内容:
1
2
3
4
5
6
7
|
let regex = /(\d{4})-(\d{2})-(\d{2})/
let string = "2019-03-12"
regex.test(string) // 这里执行正则操作即可,match等方法都可以
console.log(RegExp.$1) // 2019
console.log(RegExp.$2) // 03
console.log(RegExp.$3) // 12
|
那么如何实现上面所说等,将2019-03-12变成03/12/2019呢?直接上代码吧:
1
2
3
4
5
6
7
8
|
let regex = /(\d{4})-(\d{2})-(\d{2})/
let string = "2019-03-12"
let result = string.replace(regex, "$2/$3/$1")
console.log(result) // 03/12/2019
// 那么,如果regex = /(\d{4})-(\d{2})-\2/ 又是什么意思?
// 这里的\2表示要跟第二组的一样
|
上面这种分组有个缺点就是,如果()内还有(),这样也会形成分组,要将分组里面的分组也算进分组里面去。这样在算第几个分组的时候就要注意一下。当然,可以在不想引用的地方加上 ?: ,这个叫分组不引用,用例子可能会比较直观一点:
1
2
3
|
// regex里(19|20)\d\d)括号里面有括号,所以会有两个分组(19|20)\d\d)匹配的是$1,(19|20)匹配到的是$2,但如果我们将(19|20)算进$2,我们可以这样写regex: let regex = /((?:19|20)\d\d)-(\d{2})-(\d{2})/
let regex = /((19|20)\d\d)-(\d{2})-(\d{2})/
let string = "2019-03-12"
|
如果觉得乱,我们可以用另一种形式,就是具名的分组(只有在es2018才有,所以不是所有引擎都支持),例如:
1
2
3
4
5
6
7
|
let regex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
let string = "2019-03-12"
let result = string.match(regex)
console.log(result)
// 这里会打印一个array,array里有个group的object,里面包含了year、month、跟day的值
// let regex = /(?<year>\d{4})-(?<month>\d{2})-\k<month>/ 这时候\k<month>表示这里必须跟month那一组相同才能匹配,比如string = ‘2019-11-11’才能匹配,像string = ’2019-11-23‘就不能匹配
|
转义
如果想要匹配一些有特殊意义的字符,比如元字符、量词、{}、()等,需要用\转义
环视断言
1.根据方向的不同,分为lookahead和lookbehind
2.根据判定原则,分为肯定和否定
规则如下:
(?=pattern) 如果pattern是肯定的,那么整个表达式是肯定的
(?!pattern) 如果pattern是肯定的,那么整个表达式是否定的,即整个表达式是不匹配的
惰性与贪婪
这里需要注意的是,匹配分为贪婪匹配和惰性匹配,贪婪匹配会尽可能多地匹配,比如:
1
2
3
|
let reg = /.*\d{2,4}/
let str = '12 123 1234 12345 123456'
console.log(str.match(reg)) // "12 123 1234 12345 123456"
|
而惰性匹配,通过在量次后面加个问号就能实现惰性匹配,惰性匹配与贪婪匹配相反,尽可能少的匹配:
1
2
3
|
let reg = /.*?\d{2,4}/
let str = '12 123 1234 12345 123456'
console.log(str.match(reg)) // expect output '12'
|
修饰符与标志
- g –global
- i –ignore
- m –multiple
- y –sticky
- u –unicode
- s –dotAll
正则的方法
详情请看mdn中关于正则表达式的介绍
可视化网站
帮你更好理解正则表达式的可视化网站
常用的正则表达式
1
2
3
4
5
|
1.有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
2.非零的正整数:^[1-9]\d$
3.email地址:\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}
4.手机号校验:^1(3|4|5|6|7|8|9)\d{9}$
5.身份证校验:^\d{15}|\d{18}$
|
正则表达式应用实例(用正则表达式提取Cookie值)
不用正则的时候,我们提取cookie的值的方法可能是这样的:
1
2
3
4
5
6
7
8
9
10
|
function formatCookie() {
let cookie = document.cookie
let items = cookie.split(';')
let valueObj = {}
items.forEach(item => {
let childArr = item.split('=')
valueObj[childArr[0].trim()] = childArr[1].trim()
})
return valueObj
}
|
用正则表达式的方式则可以是这样:
1
2
3
4
5
6
7
8
9
10
|
function formatCookie() {
let cookie = document.cookie
let reg = /([^=]+)=([^;]+);?\s*/g
let result = null
let valueObj = {}
while((result = reg.exec(cookie)) !== null) {
valueObj[result[1]] = result[2]
}
return valueObj
}
|