JS正則表達式的分組匹配

什麼是分組

通俗來講,我理解的分組就是在正則表達式中用()包起來的內容表明瞭一個分組,像這樣的:正則表達式

var reg = /(\d{2})/
reg.test('12');  //true

這裏reg中的(/d{2})就表示一個分組,匹配兩位數字ide

分組內容的的形式

一個分組中能夠像上面這樣有一個具體的表達式,這樣能夠優雅地表達一個重複的字符串ui

/hahaha/
/(ha){3}/

這兩個表達式是等效的,但有了分組以後能夠更急簡潔。spa

體格分組中還能夠有多個候選表達式,例如.net

var reg = /I come from (hunan|hubei|zhejiang)/;
reg.test('I come from hunan');   //true
reg.test('I come from hubei');   //true

也就是說在這個分組中,經過|隔開的幾個候選表達式是並列的關係,因此能夠把這個|理解爲或的意思prototype

分組的分類

分組有四種類型code

  • 捕獲型 ()
  • 非捕獲型 (?:)
  • 正向前瞻型 (?=)
  • 反向前瞻型 (?!) 咱們使用的比較多的都是捕獲型分組,只有這種分組纔會暫存匹配到的串

分組的應用

分組在正則中還算使用的比較普遍的,咱們經常使用的是捕獲型分組htm

  • 捕獲與引用
    • 被正則表達式捕獲(匹配)到的字符串會被暫存起來,其中,由分組捕獲到的字符串會從1開始編號,因而咱們能夠引用這些字符串:
    var reg = /(\d{4})-(\d{2})-(\d{2})/;
    var dateStr = '2018-04-18';
    reg.test(dateStr);  //true
    RegExp.$1   //2018
    RegExp.$2   //04
    RegExp.$3   //18
  • 結合replace方法作字符串自定義替換
    • String.prototype.replace方法的傳參中能夠直接引用被捕獲的串,好比咱們想開發中常見的日期格式替換,例如後臺給你返回了一個2018/04/18,讓你用正則替換爲2018-04-18,就能夠利用分組
    var dateStr = '2018/04/18';
    var reg = /(\d{4})\/(\d{2})\/(\d{2})/;
    dateStr = dateStr.replace(reg, '$1-$2-$3') //"2018-04-18"
    不過這裏須要注意的是/是須要用\轉義的
  • 反向引用
    • 正則表達式裏也能進行引用,這稱爲反向引用:
    var reg = /(\w{3}) is \1/
    reg.test('kid is kid') // true
    reg.test('dik is dik') // true
    reg.test('kid is dik') // false
    reg.test('dik is kid') // false
    • 須要注意的是,若是引用了越界或者不存在的編號的話,就被被解析爲普通的表達式
    var reg = /(\w{3}) is \6/;
    reg.test( 'kid is kid' ); // false
    reg.test( 'kid is \6' );  // true
  • 非捕獲型分組
    • 有的時候只是爲了分組並不須要捕獲的狀況下就可使用非捕獲型分組,例如
    var reg = /(?:\d{4})-(\d{2})-(\d{2})/
    var date = '2012-12-21'
    reg.test(date)
    RegExp.$1 // 12
    RegExp.$2 // 21
  • 正向與反向前瞻型分組
    • 正向前瞻型分組:你站在原地往前看,若是前方是指定的東西就返回true,不然爲false
    var reg = /kid is a (?=doubi)/
    reg.test('kid is a doubi') // true
    reg.test('kid is a shabi') // false
    • 反向前瞻型分組:你站在原地往前看,若是前方不是指定的東西則返回true,若是是則返回false
    var reg = /kid is a (?!doubi)/
    reg.test('kid is a doubi') // false
    reg.test('kid is a shabi') // true
  • 既然前瞻型分組和非捕獲型分組都不會捕獲,那他們有什麼區別呢?先看例子:
var reg, str = "kid is a doubi";
reg = /(kid is a (?:doubi))/
reg.test(str)
RegExp.$1 // kid is a doubi

reg = /(kid is a (?=doubi))/
reg.test(str)
RegExp.$1 // kis is a

也就是說非捕獲型分組匹配到的字符串任然會被外層分組匹配到,而前瞻型不會,因此若是你但願在外層分組中不匹配裏面分組的值的話就可使用前瞻型分組了。ip

參考文章

相關文章
相關標籤/搜索