正则表达式主要还是知识点多而杂,看过很容易忘,所以,看完知识点及时练习很重要。

首先,掌握一些常用的元字符:

image

值得一说的是\b\B表示边界,可以在匹配结束时使用。

其次是掌握必要的量词意义:

image

然后我们了解一下分支与字符集的概念。

类似[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.根据判定原则,分为肯定和否定

image

规则如下: (?=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'

修饰符与标志

  1. g –global
  2. i –ignore
  3. m –multiple
  4. y –sticky
  5. u –unicode
  6. s –dotAll

正则的方法

详情请看mdn中关于正则表达式的介绍 img

可视化网站

帮你更好理解正则表达式的可视化网站

常用的正则表达式

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
}