正则表达式学习总结(三)

正则表达式回溯法原理

回溯的本质上就是深度优先搜索算法,从一初始状态开始匹配,若是匹配到尽头未遇到匹配失败,这种情况下不会发生回溯,但是尝试匹配失败时,接下来的一步就是后退一步或若干步,从 另一种可能“状态”出发,继续搜索,直到所有的“路径”(状态)都试探过,知道匹配成功,这一行为称为回溯。

贪婪量词

当多个贪婪量词挨着存在,并相互有冲突时,会尽可能多的匹配

var string = "12345";
  var regex = /(\d{1,3})(\d{1,3})/;
  console.log( string.match(regex) );
  // => ["12345", "123", "45", index: 0, input: "12345"]
// 前面匹配123,后面匹配45
1
2
3
4
5

惰性量词

惰性量词就是在贪婪量词后面加个问号。表示尽可能少的匹配

var string = "12345";
  var regex = /(\d{1,3}?)(\d{1,3})/;
  console.log( string.match(regex) );
  // => ["1234", "1", "234", index: 0, input: "12345"]
// 其中 \d{1,3}? 只匹配到一个字符 "1",而后面的 \d{1,3} 匹配了 "234"
1
2
3
4
5

分支结构

分支结构,可能前面的子模式会形成了局部匹配,如果接下来表达式整体不匹配时,仍会继续尝试剩下的分
支。这种尝试也可以看成一种回溯

var string = "candy";
  var regex = /can|candy/;
  console.log( string.match(regex) );
// ["can", index: 0, input: "candy", groups: undefined]
1
2
3
4

总结

  • 贪婪量词“试”的策略是:买衣服砍价。价钱太高了,便宜点,不行,再便宜点。
  • 惰性量词“试”的策略是:卖东西加价。给少了,再多给点行不,还有点少啊,再给点
  • 分支结构“试”的策略是:货比三家。这家不行,换一家吧,还不行,再换

正则表达式的拆分

正则表达式的结构包括字符字面量、字符组、量词、锚、分组、选择分支、反向引用的七种结构:

  • 字面量:匹配一个具体字符,包括不用转义的和需要转义的。比如 a 匹配字符 "a", 又比如 \n 匹配换行符,又比如 . 匹配小数点。
  • 字符组 :匹配一个字符,可以是多种可能之一,比如 [0-9],表示匹配一个数字。 也有 \d 的简写形式。 另外还有反义字符组,表示可以是除了特定字符之外任何一个字符,比如 [^0-9], 表示一个非数字字符,也有 \D 的简写形式。
  • 量词 :表示一个字符连续出现,比如 a{1,3} 表示 "a" 字符连续出现 3 次。 另外还有常见的简写形式,比如 a+ 表示 "a" 字符连续出现至少一次。
  • 锚:匹配一个位置,而不是字符。比如 ^ 匹配字符串的开头,又比如 \b 匹配单词边界, 又比如 (?=\d) 表示数字前面的位置。
  • 分组:用括号表示一个整体,比如 (ab)+,表示 "ab" 两个字符连续出现多次, 也可以使用非捕获分组 (?:ab)+。
  • 分支:多个子表达式多选一,比如 abc|bcd,表达式匹配 "abc" 或者 "bcd" 字符子串。 反向引用,比如 \2,表示引用第 2 个分组。

正则表达式的操作符都体现在结构中,即由特殊字符和普通字符所代表的一个个特殊整体,优先级如下:

  • 转义符:  \ 优先级为1
  • 括号和方括号: (...)、(?:...)、(?=...)、(?!...)、[...] ,优先级为 2
  • 量词限定符: {m}、{m,n}、{m,}、?、*、+ ,优先级为3
  • 位置和序列: ^、$、\元字符、一般字符, 优先级为4
  • 管道符(竖杠): | ,优先级为5

注意要点

  • 匹配字符串整体问题:匹配整个字符串,我们经常会在正则前后中加上锚 ^ 和 $,由于优先级问题位置字符和字符序列优先级要比竖杠高。需要注意的是需要吧字符和竖杠用()括起来。
    例子:/^abc|bcd$/ => /^(abc|bcd)$/
  • 量词连缀问题:
    例子:  /[1]{3}+$/ =>  /([abc]{3})+/
  • 元字符转义问题: 在 string 中, \ 字符也要转义的,也可以把每个字符转义,当然,转义后的结果仍是本身.但不是每个字符都需要转义。
    • 开头的 ^ 必须转义,不然 会把整个字符组,看成反义字符组
  • 匹配字符串 "{3,5}",只需要把正则写成 /{3,5}/,匹配字符串 "[abc]" ,可以写成 /[abc]/,也可以写成 /[abc]/
    • =、!、:、-、, 等符号,只要不在特殊结构中,并不需要转义

示例:
身份证:

let regex = /^(\d{15}|\d{17}[\dxX])$/
1

IPV4 地址:

let regex = /^((0{0,2}\d|0?\d{2}|1\d{2}|2[0-4]\d|25[0-5])\.){3}(0{0,2}\d|0?\d{2}|1\d{2}|2[0-4]\d|25[0-5])$/
1

  1. abc ↩︎
最后更新时间: 10/9/2019, 9:28:44 AM