zoukankan      html  css  js  c++  java
  • 非捕获性分组释疑

    在看人民邮电出版社出版的《JavaScript高级程序设计》
    看到7.3.4 非捕获性分组这里,书上说非捕获性分组不会创建反向引用,下面是例子:

    var sToMatch = "#123456789";
    var reNumbers = /#(?:d+)/;
    reNumbers.test(sToMatch);
    alert(RegExp.$1);

    这里alert输出是空的。

    到了第8章,又出现了类似以下的代码:

    var sToMatch = "en-us rv:0.9.4";
    var reNumbers = /rv:(d+.d+(?:.d+)?)/;
    var result = reNumbers.test(sToMatch);
    alert(RegExp.$1);

    这里alert输出就成了0.9.4
    最后那个.4是非捕获性分组捕获到的
    这里就奇怪了,为什么前面的非捕获性分组不能捕获,而嵌套的非捕获性分组就又可以捕获了?
    而且这里好像不用非捕获性分组照样可以达到相同的目的,为什么要用非捕获性分组呢?

    要了解非捕获组就要先了解捕获组,之后再了解为什么会有非捕获组的出现
    简单点说,捕获组就是把(Expression)中匹配到的内容保存到一个按“(”出现的顺序编号的组里,以供后续引用,引用的方式有反向引用,或是RegExp.$number等方式,不同的语言,支持的引用方式不同
    只要使用了(),默认为使用了捕获组,而这就带来一个问题,有些场景不得不使用(),但又不关心它匹配到的内容,比如写一个匹配24小时制HH:mm:ss的时间的正则如下
    ([01][0-9]|2[0-3])(:([0-5][0-9])){2}
    通常关心的只是整体的时间,并不关心局部的内容,这样就产生了一种副作用,将不关心的内容单独保存到内存中,只会浪费资源,降低效率
    非捕获组就是为了抵消这一副作用来产生的,非捕获组只参与匹配,但不会把匹配到的内容捕获到组里

    所以非捕获组根本就不参与编号,也就无从谈起它对应哪个$number
    在取不存在的编号的捕获组时,有些语言会返回空字符串,有些语言会报异常

    (d+.d+(?:.d+)?)中,整体是一个捕获组,按“(”出现的顺序,编号为1,(?:.d+)虽然是非捕获组,也是要参与匹配的,只是不将匹配结果单独保存到组里而已

    还需要说明的是,在绝大多数语言中,正则表达式整体对应的是$0,捕获组的编号是从1开始的

    在有些语言中,还支持(?<name>Expression)的命令捕获组语法,所以有以下两种语法属于捕获组
    (Expression)
    (?<name>Expression)
    其余的(?...)之类的语法定义的字符序列都不属于捕获组

  • 相关阅读:
    [JSOI2007][BZOJ1031] 字符加密Cipher|后缀数组
    leetcode Flatten Binary Tree to Linked List
    leetcode Pascal's Triangle
    leetcode Triangle
    leetcode Valid Palindrome
    leetcode Word Ladder
    leetcode Longest Consecutive Sequence
    leetcode Sum Root to Leaf Numbers
    leetcode Clone Graph
    leetcode Evaluate Reverse Polish Notation
  • 原文地址:https://www.cnblogs.com/newsouls/p/3782037.html
Copyright © 2011-2022 走看看