JavaScript正則表達式總結

正則表達式一直是js裏比較難以掌握的點。 看不懂,學不會,記不住。 每次須要用到正則的時候,都須要再去查找資料。 今天花時間把正則的知識點總結下,但願能在理解的基礎上熟練掌握。javascript

正則表達式的做用

正則表達式在字符串處理方面發揮着巨大的做用,掌握了它,就能針對某一特定模式的字符串或者批量對字符串進行處理。 雖然各個編程語言對正則的支持不一樣,可是差別並不大。 這裏只介紹js語言中正則的使用方法。java

javascript對正則表達式的支持

先看一段代碼:es6

var formatPrice = function(price){
  return price.toString().replace(/\B(?=(\d{3})+$)/g, ',');
}

這個formatPrice函數將商品總價轉化爲每三位以','分割的字符串,這是業務中常遇到的狀況。 能夠看到,經過使用正則,代碼變得至關的簡潔。正則表達式

在js中建立正則的兩種方式

  • 使用字面量

/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

正則表達式的語法

flags - 標識符

  • g - global,全局匹配,找到全部的匹配,而不是在第一個匹配後中止
  • i - ignoreCase 忽略大小寫
  • m - multiline 多行搜索,不使用'm'模式時,整個字符串會被當作一行,換行符也被當作正則裏的一個字符,使用'm'模式時,字符串換行後的內容會被當作新的一行。

元字符

正則表達式有兩種基本字符類型組成:函數

  1. 原義字符 - 表明他們自己含義的字符
  2. 元字符 - 在正則表達式中有特殊含義的非字母字符

好比: . * + ? () [] {} ^ $ | \

字符類

  • . - 匹配任意單個字符,行結束符除外
  • \d - 匹配任意阿拉伯數字,至關於[0-9]
  • \D - 匹配任意一個不是阿拉伯數字的字符,至關於1, 這裏^用在[]中表示取反的意思。
  • \w - 匹配任意阿拉伯字母,數字和下劃線, 至關於[0-9a-zA-Z_]
  • \W - 與w相反, 至關於2
  • \s - 匹配一個空白符,包括空格符,製表符,換行符,換頁符和其餘空格字符。
  • \S - 匹配一個非空白符,與上面相反
  • \t - 匹配一個水平製表符
  • \r - 匹配一個回車符
  • \n - 匹配一個換行符
  • \v - 匹配一個垂直製表符
  • 還有其餘一些不經常使用的字符類,具體可查閱MDN文檔

字符集合

  • [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)就至關於給正則加的一個限制條件 -- 表示匹配項不只要符合正則表達式,並且要符合斷言給出的條件。

  • 正向前瞻 - exp(?=assert),好比/\d{2}(?=a)/ 表示匹配兩個數字且後面必須有字母a跟隨
  • 負向前瞻 - exp(?!assert),好比/\d{2}(?!a)/ 表示匹配兩個數字且後面沒有字母a跟隨

注意: 斷言只是至關於正則的條件,並不會真正的匹配相應的字符。

咱們再來分析開頭給出的那段代碼:

price.toString().replace(/\B(?=(\d{3})+$)/g, ',');
正則 /\B(?=(\d{3})+$)/g中,
\d{3}+$表示以一個或多個三個數字結尾,
?=表示這部分是斷言,是正則的條件,即匹配一個零寬的非單詞邊界,且後面有(3,6,9...)個數字字符的狀況

js中正則表達式api

正則的實例屬性

一個正則表達式的實例具備如下一些實例屬性

  • multiline - 布爾值,表示正則是否多行匹配,對應於標誌中的'm'
  • global - 布爾值,表示是否全局匹配,對應於標誌中的'g'
  • ignoreCase - 布爾值,表示是否忽略大小寫,對應於標誌中的'i'
  • source - 字符串,是正則表達式模式的字符串表示,好比/\d{2}ac/gi的source屬性就是'\d{2}ac', 該值不會包含正則兩邊的//和標誌gi,也不會像構造函數參數那樣對\進行轉義。
  • lastIndex - 整數,表示下一次匹配的起始位置,該值只有在'g'模式下才有用,在不全局匹配時始終是0

正則的實例方法

正則表達式主要有兩個實例方法test和exec。
假設regexp表示一個正則的實例,str表示一個字符串,那麼

  • regexp.test(str) - 返回一個布爾值,若是找到匹配項,返回true,不然false。
  • reg.exex(str) - 返回一個數組, 數組第一項爲匹配到的字符串,後面項依次爲分組捕獲到的信息,該數組還具備input和index兩個屬性,input表示進行匹配的字符串 - 即參數str,index表示匹配到的字符串的起始位置。

這裏要注意的是:應用了全局'g'標誌和沒有全局'g'標誌的同一個模式的正則,對於同一個字符串,兩種方法的表現多是不一樣的。 由於若是沒有全局標識,每次都會從字符串起始位置0開始匹配,而應用了'g',會從上次匹配的結束位的下一位開始匹配。

正則的靜態屬性

正則的構造函數RegExp具備一些靜態屬性,這些屬性中保存着最新一次正則匹配的信息。
好比RegExp.$1-$9中,保存着最近一次匹配中分組捕獲到的信息。
還有一些其餘的靜態屬性,但平時使用較少,再也不介紹,具體可查閱MDN文檔。

字符串中使用正則的一些方法

  • String.prototype.search(regexp) - 返回匹配到的子字符串的索引或者-1, 會忽略正則中的'g'標誌
  • String.prototype.match(regexp) - 返回一個數組,這裏是否有'g'標識會對返回值產生影響,若是正則沒有'g'標誌,那麼返回的數組的上面正則的exec返回的數組形式相同。 若是有'g'標誌,返回的是一個包含全部匹配子字符串的數組,且該數組也再也不有input和index屬性。
  • String.prototype.split(regexp) - split的參數除了是一個字符串外,還能夠是一個正則表達式。
  • String.prototype.replace(str|regexp, replaceStr|function)

字符串的replace是一個很是強大的方法,來看一個例子:

//咱們想把'a1b2c3d4e5'這個字符串替換成字母后數字都加1,變成'a2b3c4d5e6'
'a1b2c3d4e5'.replace(/\d/g, function(match, index, origin){
    return parseInt(match) + 1
  })

以上就是關於正則的所有總結,精力有限,寫的比較亂,見諒。
這裏推薦一個很是好的介紹js正則表達式的課程慕課網-javaScript正則表達式

參考

《javascript高級程序設計》
Regexper正則圖形化工具
MDN正則表達式


  1. 0-9
  2. A-Za-z0-9_
相關文章
相關標籤/搜索