什么是分組
通俗來說,我理解的分組就是在正則表達式中用()包起來的內容代表了一個分組,像這樣的:
var reg = /(\d{2})/
reg.test('12'); //true
這里reg中的(/d{2})就表示一個分組,匹配兩位數字
分組內容的的形式
一個分組中可以像上面這樣有一個具體的表達式,這樣可以優雅地表達一個重復的字符串
/hahaha/
/(ha){3}/
這兩個表達式是等效的,但有了分組之后可以更急簡潔。
體格分組中還可以有多個候選表達式,例如
var reg = /I come from (hunan|hubei|zhejiang)/;
reg.test('I come from hunan'); //true
reg.test('I come from hubei'); //true
也就是說在這個分組中,通過|隔開的幾個候選表達式是並列的關系,所以可以把這個|理解為或的意思
分組的分類
分組有四種類型
- 捕獲型 ()
- 非捕獲型 (?😃
- 正向前瞻型 (?=)
- 反向前瞻型 (?!)
我們使用的比較多的都是捕獲型分組,只有這種分組才會暫存匹配到的串
分組的應用
分組在正則中還算使用的比較廣泛的,我們常用的是捕獲型分組
- 捕獲與引用
- 被正則表達式捕獲(匹配)到的字符串會被暫存起來,其中,由分組捕獲到的字符串會從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
也就是說非捕獲型分組匹配到的字符串任然會被外層分組匹配到,而前瞻型不會,所以如果你希望在外層分組中不匹配里面分組的值的話就可以使用前瞻型分組了。