zoukankan      html  css  js  c++  java
  • 【转】正则基础之——非捕获组

    源地址

      

     

    非捕获组:(?:Expression)

    接触正则表达式不久的人,通常都会对非捕获比较迷惑,为什么要有非捕获组?作用是什么?应该在什么场景下使用?

    说到非捕获组,首先要了解什么是捕获组,详细内容参考正则基础之——捕获组(capture group 

    1、为什么要有非捕获组

    一旦使用了“()”,就会默认为是普通捕获组,从而将“()”内表达式匹配的内容捕获到组里。但是有些情况下,不得不用“()”,但并不关心“()”中匹配的内容是什么,后面也不会引用捕获到的内容,这带来了一个副作用,记录这些捕获组就会占用内存,降低匹配效率。

    设计非捕获组的目的就是为了抵消这种副作用。 只进行分组,并不将子表达式匹配到的内容捕获到组里。

    2、不得不使用(),由此可能带来副作用的情况

    以下举例中只说明场景,举例比较简单,实际应用涉及到时可能会比较复杂。

    a)         使用“|”表示“或”的关系时,用“()”限制范围

    举例:匹配0100的数字

    正则表达式:^([1-9]?[0-9]|100)$

    如果不用“()”来限制“|”的范围,结果就会出错,详见“|”的解释。

    b)         使用量词限定一个子表达式整体的匹配次数

    举例:匹配HH:mm:ss格式时间

    正则表达式:([01][0-9]|2[0-3])(:[0-5][0-9]){2}

    这里的“{2}”是对前面的“:[0-5][0-9]”整体作修饰,因此要用“()”来限定修饰的范围。

    当然,量词还可以是?*+{m}{m,n}{m,},以及非贪婪模式的量词等。

    c)         某些时候为了使捕获组的编号可控,可能会用到非捕获组,这种应用不多,这里不赘述。

    3、什么时候该用非捕获组

    非捕获组主要是在涉及到效率时才考虑使用,而效率通常都是相对的,需要综合考虑。

    不考虑效率的场合,可以不用非捕获组,以提高正则表达式的可读性。

    一些非常简单的正则中,如果使用了非捕获组,因为要解析这种语法,反而可能会降低匹配效率。

    一般在较复杂,“()”使用较多的正则表达式中可以考虑使用非捕获组,比如验证日期的正则表达式。

    未使用非捕获组的正则:

    ^((?!0000)[0-9]{4}-((0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-8])|(0[13-9]|1[0-2])-(29|30)|(0[13578]|1[02])-31)|([0-9]{2}(0[48]|[2468][048]|[13579][26])|(0[48]|[2468][048]|[13579][26])00)-02-29)$

    由于这里的“()”都是用作分组,并不关心分组匹配到的内容,而且使用的()很多,影响匹配效率,所以这个正则表达式中可以使用非捕获组。

    ^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$

     

  • 相关阅读:
    298. Binary Tree Longest Consecutive Sequence
    117. Populating Next Right Pointers in Each Node II
    116. Populating Next Right Pointers in Each Node
    163. Missing Ranges
    336. Palindrome Pairs
    727. Minimum Window Subsequence
    211. Add and Search Word
    年底购物狂欢,移动支付安全不容忽视
    成为程序员前需要做的10件事
    全球首推iOS应用防破解技术!
  • 原文地址:https://www.cnblogs.com/pmars/p/2308637.html
Copyright © 2011-2022 走看看