正則表達式一直是js裏比較難以掌握的點。 看不懂,學不會,記不住。 每次須要用到正則的時候,都須要再去查找資料。 今天花時間把正則的知識點總結下,但願能在理解的基礎上熟練掌握。javascript
正則表達式在字符串處理方面發揮着巨大的做用,掌握了它,就能針對某一特定模式的字符串或者批量對字符串進行處理。 雖然各個編程語言對正則的支持不一樣,可是差別並不大。 這裏只介紹js語言中正則的使用方法。java
先看一段代碼:es6
var formatPrice = function(price){ return price.toString().replace(/\B(?=(\d{3})+$)/g, ','); }
這個formatPrice函數將商品總價轉化爲每三位以','分割的字符串,這是業務中常遇到的狀況。 能夠看到,經過使用正則,代碼變得至關的簡潔。正則表達式
/pattern/flags
, 這就是正則表達式的字面量語法,pattern表示正則表達式的模式,flags爲正則表達式的標誌。好比: /a[bc]\d{2}$/gi
。
其中模式和標誌的知識將會在後面詳細介紹。
字面量形式的正則表達式通常使用較多,也推薦你們儘量使用這種形式,簡潔易讀,符合正常的使用習慣。編程
除了使用字面量外,還可使用構造函數生成正則表達式。 new RegExp(pattern [, flags])
, 好比:var reg= new RegExp('[a-zA-Z]+\\d$', 'gi')
這裏構造函數的兩個參數,第一個參數能夠是字符串(es5及之前)或正則表達式(es6),第二個可選參數爲字符串。
當咱們事前不能肯定正則表達式的值時,或者正則依賴第三方輸入來動態生成正則時,須要使用這種方式。
這裏要注意的一點是:第一個參數爲一個字符串時,當咱們使用正則裏的特殊字符,好比\d
或\b
等時,須要對\
進行轉義,也就是寫成\\d
或\\b
的形式,由於\
在字符串裏有特殊含義。api
因爲正則的使用場景主要是字符串處理,因此字符串類提供了不少方法使用正則表達式。好比:數組
str.replace(regexp|substr, newSubStr|function) str.search(regexp) str.match(regexp) str.split([separator[, limit]])
另外,正則表達式自己也提供了處理字符串的方法,好比:regexObj.exec(str)
regexObj.test(str)
編程語言
這些方法將再後面介紹ide
正則表達式有兩種基本字符類型組成:函數
好比: . * + ? () [] {} ^ $ | \
.
- 匹配任意單個字符,行結束符除外\d
- 匹配任意阿拉伯數字,至關於[0-9]\D
- 匹配任意一個不是阿拉伯數字的字符,至關於1, 這裏^
用在[]中表示取反的意思。\w
- 匹配任意阿拉伯字母,數字和下劃線, 至關於[0-9a-zA-Z_]\W
- 與w相反, 至關於2 \s
- 匹配一個空白符,包括空格符,製表符,換行符,換頁符和其餘空格字符。\S
- 匹配一個非空白符,與上面相反\t
- 匹配一個水平製表符\r
- 匹配一個回車符\n
- 匹配一個換行符\v
- 匹配一個垂直製表符[abc]
- 又叫字符組,表示匹配集合中的任意一個字符,能夠用-
來指定範圍[^abc]
- 反義字符組,匹配不是集合中字符的一個字符,能夠用-
來指定範圍^
- 不使用在[]中時,表示匹配輸入開始$
- 匹配輸入結尾\b
- 匹配零寬單詞邊界\B
- 匹配零寬非單詞邊界,與上面b含義相反。?
- 匹配0次或1次+
- 匹配一次或屢次*
- 匹配0次或屢次{n}
- 匹配n次{m,n}
- 匹配最少m次,最多n次{m,}
- 匹配最少m次舉個例子, /\d{3,6}/g
,這樣一個正則表達式若是匹配字符串'234955033',是匹配3或4,5,6個數字呢?
js中正則表達式會默認儘量多的匹配,也就是匹配6個數字,即貪婪模式。
非貪婪模式則是讓正則表達式儘量少的匹配,也就是隻匹配3個數字,正則要使用非貪婪模式,只須要在量詞後面加上?
便可。
下面一個例子:
'123456789'.replace(/\d{3,6}/g, 'X') //貪婪模式,結果爲'XX' '123456789'.replace(/\d{3,6}?/g, 'X') //非貪婪模式,結果爲'XXX'
()
- 將正則表達式分組,以控制量詞的做用範圍,好比:baron{3}
和 (baron){3}
,兩者是有區別的。|
- 表示 或,也能夠配合()進行使用,好比: foo|bar 和 fo(o|b)ar有時,咱們在匹配到正則對應的字符串時,還想要使用匹配到的部份內容,這時候可使用$1,$2,$3等符號引用分組捕獲的內容。
好比:
'12/03/2017'.replace(/(\d{2})\/(\d{2})\/(\d{4})/, '$3-$1-$2') //輸出2017-12-03
這裏爲了得到年月日的引用,使用()給正則添加了三個分組,而後就能夠從前日後分別用$1 $2 $3
代替分組捕獲的內容。
全部()裏匹配到的內容默認都會被捕獲到,有時候,咱們只是想要使用()簡單的分組功能,而不須要讓正則表達式捕獲分組內容,此時,只須要在分組內添加?:
便可,好比:
'12/03/2017'.replace(/(\d{2})\/(?:\d{2})\/(\d{4})/, '$2-$1') //輸出2017-12月,第二個分組的內容被忽略。
這裏出現了三個新的概念,但其實他們也很簡單。
首先,咱們要分清何爲前,何爲後。
正則匹配字符串是從前日後解析,因此,往字符串尾部方向叫前瞻,往字符串頭部方向叫後顧。
js中的正則表達式支持前瞻不支持後顧,因此這裏只介紹前瞻。
前瞻通常結合斷言使用,其實斷言(assert)就至關於給正則加的一個限制條件 -- 表示匹配項不只要符合正則表達式,並且要符合斷言給出的條件。
/\d{2}(?=a)/
表示匹配兩個數字且後面必須有字母a跟隨/\d{2}(?!a)/
表示匹配兩個數字且後面沒有字母a跟隨注意: 斷言只是至關於正則的條件,並不會真正的匹配相應的字符。
咱們再來分析開頭給出的那段代碼:
price.toString().replace(/\B(?=(\d{3})+$)/g, ','); 正則 /\B(?=(\d{3})+$)/g中, \d{3}+$表示以一個或多個三個數字結尾, ?=表示這部分是斷言,是正則的條件,即匹配一個零寬的非單詞邊界,且後面有(3,6,9...)個數字字符的狀況
一個正則表達式的實例具備如下一些實例屬性
/\d{2}ac/gi
的source屬性就是'\d{2}ac'
, 該值不會包含正則兩邊的//
和標誌gi
,也不會像構造函數參數那樣對\
進行轉義。正則表達式主要有兩個實例方法test和exec。
假設regexp表示一個正則的實例,str表示一個字符串,那麼
這裏要注意的是:應用了全局'g'標誌和沒有全局'g'標誌的同一個模式的正則,對於同一個字符串,兩種方法的表現多是不一樣的。 由於若是沒有全局標識,每次都會從字符串起始位置0開始匹配,而應用了'g',會從上次匹配的結束位的下一位開始匹配。
正則的構造函數RegExp具備一些靜態屬性,這些屬性中保存着最新一次正則匹配的信息。
好比RegExp.$1-$9中,保存着最近一次匹配中分組捕獲到的信息。
還有一些其餘的靜態屬性,但平時使用較少,再也不介紹,具體可查閱MDN文檔。
字符串的replace是一個很是強大的方法,來看一個例子:
//咱們想把'a1b2c3d4e5'這個字符串替換成字母后數字都加1,變成'a2b3c4d5e6' 'a1b2c3d4e5'.replace(/\d/g, function(match, index, origin){ return parseInt(match) + 1 })
以上就是關於正則的所有總結,精力有限,寫的比較亂,見諒。
這裏推薦一個很是好的介紹js正則表達式的課程慕課網-javaScript正則表達式
《javascript高級程序設計》
Regexper正則圖形化工具
MDN正則表達式