关于javascript:javascript正则高级用法

3次阅读

共计 2911 个字符,预计需要花费 8 分钟才能阅读完成。

先简略看几个罕用根底标识符

^ 匹配一个输出或一行的结尾,

  /^a/
  // 匹配 "an A",而不匹配 "An a"

$ 匹配一个输出或一行的结尾

/a$/
// 匹配 "An a",而不匹配 "an A"

* 匹配后面元字符 0 次或屡次

/ba*/
// 匹配 b,ba,baa,baaa,...

+ 匹配后面元字符 1 次或屡次

/ba+/
// 匹配 ba,baa,baaa,...

? 匹配后面元字符 0 次或 1 次

/ba?/
// 匹配 b,ba
(x) // 匹配 x 保留 x 在名为 $1...$9 的变量中
x|y // 匹配 x 或 y
{n} // 准确匹配 n 次
{n,} // 匹配 n 次以上
{n,m} // 匹配 n - m 次
[xyz] // 字符集,匹配这个汇合中的任一一个字符(或元字符),匹配 x,y,z
[^xyz] // 不匹配这个汇合中的任何一个字符

正则表达式 (Regular Expression) 其实是一门工具,通过字符串模式匹配,实现搜寻和替换性能。

它起源于 20 世纪 50 年代科学家在数学畛域做的一些钻研工作,起初才被引入到计算机领域中。

从它的命名咱们能够晓得,它是一种用来形容规定的表达式。而它的底层原理也非常简略,就是应用 状态机 的思维进行模式匹配。

这里先不细纠概念,罕用的办法属性,文档 mdn 什么都有,也不纠结,直奔主题。

子表达式

子表达式 (Reg) 具备独立的匹配性能,保留独立的匹配后果

  1. 作为独立单元能够应用 *+?{n,m}等量词

    /(ab)?c)/ 
    // 匹配 c 或者 abc
  2. 作为子模式能够独立解决,并且保留匹配后果子串, 可通过 RegExp.$1,…$n 拜访

    var re = /(\w+)\s(\w+)/;
    var str = "John Smith";
    var newstr = str.replace(re, "$2, $1");
    console.log(newstr); // Smith, John

    以下 RegExp 属性,不是 w3c 规范,不过大部浏览器反对

    RegExp 属性 形容
    $n 第 n 个子表达式匹配的字符串, 只有 1 -9
    $& 最初匹配到的字符串,RegExp.lastMatch 别名
    $’ 最新匹配的右侧子串,RegExp.rightContext 别名
    $` 最新匹配的左侧子串,RegExp.leftContext 别名
    $+ 匹配到的最初一个子串,RegExp.lastParen 别名
    $_ 被匹配胜利的原字符串,RegExp.input 别名

    对应 replace 函数中拜访正则后果的参数

    变量名 形容
    $n 插入第 n 个子表达式匹配的字符串, 只有 1 -99
    $& 插入匹配的子串
    $’ 插入以后匹配的子串左边的内容
    $` 插入以后匹配的子串右边的内容
    $<name> 匹配 [Name] 具名子表达式的字符串
  3. 回溯援用 (反向援用), 模式的前面局部援用后面子表达式曾经匹配到的子字符串
    通过反斜杠 \ 加数字来实现的。数字代表子表达式在该正则表达式中的程序。例如: \1 援用的是 第一 个子表达式的 匹配后果

    匹配后果 不是匹配模式

    var s = "<h1>title<h1><p>text<p>";
    var r = /(<\/?\w+>).*\1/g;
    // 相当于 /(<\/?\w+>).*(<h1>|<p>)/g
    // 再加 (<\/?\w+>) 匹配后果 === (<h1>|<p>)匹配后果
    var a = s.match(r);  // 返回数组["<h1>title<h1>","<p>text<p>"]

子表达式的高级模式

非捕捉模式, 匹配后果不会保留

/(?:\w+)\s(\w+)/
// ?: 标识非捕捉
// $1 从第二个子表达式开始计算

命名捕捉,这个用的较少

var re = /(?<myName>\w+)\s(\w+)/;
console.log("John Smith".match(re));
// (?<Name>x)
// 匹配后果保留在匹配项的 groups 属性中

断言

断言用来限度正则匹配的边界。

其实 ^,&,\b,\B 也是断言。

  • ^ 对应字符串结尾
  • & 字符串结尾
  • \b 单词边界
  • \B 非单词边界

这里次要说其余四种断言

  1. 后行断言,/x(?=y)/ y 在前面追随 x 的时候匹配 x
  2. 后行否定断言,/x(?!y)/ y 没有在前面追随 x 的时候匹配 x
  3. 后行断言,/(?<=y)x/ y 在 x 后面紧随的时候匹配 x
  4. 后行否定断言,/(?<!y)x/ y 没有在 x 后面紧随的时候匹配 x

    // 后行断言
    let regex = /First(?= test)/g;
    console.log('First test'.match(regex)); // ['First']
    
    // 后行否定断言
    // /\d+(?!\.)/ 匹配没有被小数点追随且至多有一位的数字。/\d+(?!\.)/.exec('3.141') 匹配 "141" 而不是 "3"
    console.log(/\d+(?!\.)/g.exec('3.141')); // ['141', index: 2, input: '3.141']
    
    // abc 前面不能追随 de
    let reg = /abc(?!de)/;
    reg.test('abcdefg');  // false;
    reg.test('abcd');  // true;
    reg.test('abcabc');   // true;

正则表达式的三种模式

在应用润饰匹配次数的特殊符号时,有几种示意办法能够使同一个表达式可能匹配不同的次数,比方:”{m,n}”, “{m,}”, “?”, “*”, “+”,具体匹配的次数随被匹配的字符串而定。

  1. 贪心模式
    贪心模式总是尽可能多的匹配

    var regex = /\d{2,5}/g;
    var string = "123 1234 12345 123456";
    console.log(string.match(regex) );
    // => ["123", "1234", "12345", "12345"]
  2. 懈怠模式
    在润饰匹配次数的特殊符号后再加上一个 “?” 号,则能够使匹配次数不定的表达式尽可能少的匹配,使可匹配可不匹配的表达式,尽可能的 “ 不匹配 ”

    var regex = /\d{2,5}?/g;
    var string = "123 1234 12345 123456";
    console.log(string.match(regex) );
    // => ["12", "12", "34", "12", "34", "12", "34", "56"]
    其中 /\d{2,5}?/ 示意,尽管 2 到 5 次都行,当 2 个就够的时候,就不再往下匹配
  3. 独占模式 (js 不反对)
    如果在表达式后加上一个加号(+),则会开启独占模式。同贪心模式一样,独占模式一样会匹配最长。不过在独占模式下,正则表达式尽可能长地去匹配字符串,一旦匹配不胜利就会完结匹配而不会回溯。

正则的性能

正则引擎次要的两大类:一种是 DFA(确定型有穷自动机),另一种是 NFA(不确定型有穷自动机)。NFA 对应正则表达式主导的匹配,DFA 对应文本主导的匹配。

DFA 从匹配文本动手,从左到右,每个字符不会匹配两次,它的工夫复杂度是多项式的,所以通常状况下,它的速度更快,但反对的个性很少,不反对捕捉组、各种援用等等;

NFA 则是从正则表达式动手,一直读入字符,尝试是否匹配以后正则,不匹配则吐出字符从新尝试,通常它的速度比较慢,最优工夫复杂度为多项式,最差状况为指数级

NFA 反对更多的个性,因此绝大多数编程场景下(包含 java,js),咱们面对的是 NFA。

吐出字符从新尝试就是 回溯

正则表达式回溯法原理

正文完
 0