下面的正則表達式能夠匹配kidkidkid
:正則表達式
/kidkidkid/
而另外一種更優雅的寫法是:函數
/(kid){3}/
這裏由圓括號包裹的一個小總體稱爲分組。prototype
一個分組中,能夠有多個候選表達式,用|
分隔:code
var reg = /I love (him|her|it)/; reg.test('I love him') // true reg.test('I love her') // true reg.test('I love it') // true reg.test('I love them') // false
這裏的|
至關於「或」的意思。字符串
被正則表達式匹配(捕獲)到的字符串會被暫存起來。其中,由分組捕獲的串會從1開始編號,因而咱們能夠引用這些串:get
var reg = /(\d{4})-(\d{2})-(\d{2})/ var date = '2010-04-12' reg.test(date) RegExp.$1 // 2010 RegExp.$2 // 04 RegExp.$3 // 12
$1
引用了第一個被捕獲的串,$2
是第二個,依次類推。博客
replace
配合String.prototype.replace
方法的傳參中能夠直接引用被捕獲的串。好比咱們想將日期12.21/2012
改成2012-12-21
:it
var reg = /(\d{2}).(\d{2})\/(\d{4})/ var date = '12.21/2012' date = date.replace(reg, '$3-$1-$2') // date = 2012-12-21
順道一提,給replace
傳迭代函數,有時能優雅地解決一些問題。io
將違禁詞轉換爲等字數的星號是一個常見功能。好比文本是kid is a doubi
,其中kid
與doubi
是違禁詞,那麼轉換後應該爲*** is a *****
。咱們能夠這麼寫:function
var reg = /(kid|doubi)/g var str = 'kid is a doubi' str = str.replace(reg, function(word){ return word.replace(/./g, '*') })
若是碰到相似/((kid) is (a (doubi)))/
的嵌套分組,捕獲的順序是什麼?來試試:
var reg = /((kid) is (a (doubi)))/ var str = "kid is a doubi" reg.test( str ) // true RegExp.$1 // kid is a doubi RegExp.$2 // kid RegExp.$3 // a doubi RegExp.$4 // doubi
規則是以左括號出現的順序進行捕獲。
正則表達式裏也能進行引用,這稱爲反向引用:
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
\1
引用了第一個被分組所捕獲的串,換言之,表達式是動態決定的。
注意,若是編號越界了,則會被當成普通的表達式:
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
這個例子中,(?:\d{4})
分組不會捕獲任何串,因此$1
爲(\d{2})
捕獲的串。
就好像你站在原地,向前眺望:
正向前瞻型分組 - 你前方是什麼東西嗎?
負向前瞻型分組 - 你前方不是什麼東西嗎?
太拗口了,我喜歡稱之爲確定表達式與否認表達式。先舉個正向前瞻的例子:
var reg = /kid is a (?=doubi)/ reg.test('kid is a doubi') // true reg.test('kid is a shabi') // false
kid is a
後面跟着什麼?若是是doubi
才能匹配成功。
而負向前瞻則恰好相反:
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
可見,非捕獲型分組匹配到的串,仍會被外層的捕獲型分組捕獲到,但前瞻型卻不會。當你須要參考後面的值,又不想連它一塊兒捕獲時,前瞻型分組就派上用場了。
最後,JS不支持後瞻型分組。
原創,自由轉載,請署名,本人博客 kid-wumeng.me謝謝