1. 程式人生 > >正則表示式Regular Expression

正則表示式Regular Expression

什麼是 RegExp?

RegExp 是正則表示式的縮寫。

 正則表示式( regular expression)描述了一種字串匹配的模式。可以用來:

(1)檢查一個串中是否含有符合某個規則的子串,並且可以得到這個子串;

(2)根據匹配規則對字串進行靈活的替換操作

正則表示式線上測試網站,https://regexper.com/ 

通過該網站,可以通過圖形化的介面去領會正則表示式的含義,將更加直觀和容易理解

RegExp物件:

  JavaScript通過內建物件RegExp來支援正則表示式

  有兩種方法例項化RegExp物件:

  1、字面量  :如 var reg = /\bis\b/g;

    2、建構函式 : 如 var reg = new RegExp('\\bis\\b','g'); 

    修飾符: g:global全文搜尋,不新增,搜尋到第一個匹配就停止

         i:ignore case忽略大小寫,預設大小寫敏感 

          m:multiple lines 多行搜尋 

正則表示式主要有一下兩種字元組成:

1、原義文字字元(普通字元):

  字母、數字、漢字、下劃線、以及沒有特殊定義的標點符號,都是"普通字元"表示式中的普通字元。在匹配一個字串的時候,匹配與之相同一個字元 如:a,b,

2、元字元:

  指的是在正則表示式中具有特殊含義的非字母字元(轉義字元) ,如\n換行符  \t水平製表符  \v垂直製表符 \r回車符 \o空字元 \f換頁符 \cX與X對應的控制字元(ctrl+x)

  特殊元字元:. * + $ ^| \(){}[]

字元類:

  使用元字元[]來構建的一個簡單類,所謂類是指符合某些特性的物件,一個泛指,而不是特質某一個字元,如:[abc]把字元a、b、c歸為一類,表示式可以匹配這些字元

[abc] 

範圍類:

  可以使用[a-z]來連線兩個字元,表示從a到z的任意字元,這是個閉區間,包含了a和z字元

  在[]組成的類內部是可以連寫的,比如[a-zA-Z]

預定義類和邊界

  匹配一個ab+數字+任意字元 的字串 如:ab[0-9][^\r\n]

  

   正則表示式提供了幾個常用的邊界表示式,如圖

  

  

  

  

  注意:^放在[]裡面,就表示除xxx字元之外,放在外面則表示以xxx開始

量詞:

  如果希望一個連續出現20次的數字字串,可以採取這種形式 \d{20}

  \d{20}\w\d?\w+\d*\d{3}\w{3,5}\d{3,}

  

    

貪婪模式和非貪婪模式:

  貪婪模式:\d{3,6} ,儘可能多的匹配

  非貪婪模式:讓正則表示式儘可能少的匹配,也就是說一旦成功匹配了就不再嘗試,在後面加個?號即可

分組:

  配置字串Byron連續出現3次的場景,

  Byron{3}   實際效果:

  () 圓括號: 可以達到分組的功能,使量詞作用於分組

   |或:使用|可以達到或的效果 Byron | Casper 

  也可以這樣結合分組使用 Byr(on|Ca)sper     

  選擇出來的是符合Byronsper或者ByronCasper

  反向引用

   將2015-12-25 =>12/25/2015

前瞻:

  正則表示式從文字頭部向尾部開始解析,文字尾部方向,稱為‘前’

  前瞻就是在正則表示式匹配到規則的時候,向前檢查是否符合斷言,後顧/後瞻方向相反

  javascript不支援後顧

  符合和不符合特定斷言稱為肯定/正向匹配否定/負向匹配

    \w(?=\d)

    \w(?!\d)

   分析:從第一個字元'a'開始,滿足\w,後跟'2',符合斷言'\d’,因此a被X所替換

    分析同上

物件屬性:

    global全文搜尋,不新增,搜尋到第一個匹配就停止 預設值false

    ignore case忽略大小寫,預設大小寫敏感 預設值false

      multiple lines 多行搜尋 ,預設值false

    lastIndex:是當前表示式匹配內容的最後一個字元的下一個位置

    source:正則表示式的文字字串

    這幾個屬性都是隻讀的,不能手動設定 

RegExp的test和exec方法:

  RegExp.prototype.test(str) :

  用於測試字串引數中是否存在匹配正則表示式模式的字串

  如果存在,返回true,否則返回false

給其加上g後,判斷ab是存在匹配該模式的字元,  ,從結果看來,當執行到第三次,結果變成了false,其實是lastIndex這個屬性在作用,原因在於正則表示式執行了test方法後都會作用到正則表示式本身的結果。,可以看到執行兩次後,lastIndex的值變為了2

分析:當前匹配結果,就是a,當前匹配結果的最後一個結果,還是a,當前匹配結果的最後一個結果的下一個結果,那就是b,此時lastIndex的值就是1了。那麼在執行一次,lastIndex的結果就是2,看來test方法執行,其lastIndex並不是每次都是從頭開始的,那麼第3次執行的時候,lastIndex就被重置為0了。

如果測試的是reg1.test('a');那麼其返回的結果,只有奇數次是true。因為我們用test的方法時候,只是為了測試是否存在某個字元而已,因此就沒有必要加上g標誌了。

  RegExp.prototype.exec(str)

  使用正則表示式模式對字串執行搜尋,並更新全域性RegExp物件的屬性以反應匹配結果

  如果沒有匹配的文字則返回null,否則返回一個結果陣列 

    -index  宣告匹配文字的第一個字元的位置

    -input 存放被檢索的字串String

  非全域性呼叫:

   *呼叫非全域性的RegExp物件的exec()時,返回陣列

   *第一個元素是與正則表示式相匹配的文字

   *第二個元素是與RegExpObject的第一個子表示式相匹配的文字(如果有的話)

       *第三個元素是與RegExp物件的第二個子表示式相匹配的文字(如果有的話,依次類推)

  注意了:在非全域性的情況下,lastIndex根本就不生效

 

 以上是非全域性和全域性呼叫的結果

字串物件方法:

  String.prototype.search(reg)

  *search()方法用於檢索字串中指定子字串,或檢索與正則表示式相匹配的子字串

  *方法返回第一個匹配結果 index,查詢不到返回-1

  *search()方法不執行全域性匹配,它將忽略標誌g,並且總是從字串的開始進行檢索

  ‘a1b2c3’.search('1');返回1,會將其轉換成正則表示式 ‘a1b2c3’.search(/1/);返回1,如果傳入的引數不是正則,則會嘗試轉換成正則表示式

  String.prototype.match(reg)

  非全域性呼叫:

  如果regexp沒有標誌g,那麼match()方法就只能在字串中執行一次匹配

  如果沒有找到任何文字,將返回null

  否則它將返回一個數組,其中存放了與它找到的匹配文字有關的資訊

  返回資料的第一個元素存放的是匹配文字,而其餘的元素存放的是與正則表示式的子表示式(如分組)匹配的文字

  除了常規的陣列元素之外,返回的陣列還含有2個物件屬性

  -index 宣告匹配文字的起始字元在字串中的位置

  -input宣告對stringObject的引用

  全域性呼叫:

  如果regexp具有標誌g,則match方法將執行全域性搜尋,找到字串中所有匹配子字串

  *沒有找到任何匹配的子串,則返回null

  *如果找到了一個或多個匹配子串,則返回一個數組

  陣列元素中存放的是字串中所有匹配子串,而且也沒有index屬性或input屬性

  以上是非全域性和全域性呼叫結果,非全域性下,lastIndex不起作用,其ret中的a是分組的字元。在全域性條件下ret的結果為1a2,3c4

  Sting.propotype.split(reg)

  我們經常使用split方法把字串分割為字元陣列

  'a1b2c3d4e5',split(/\d/); 

  String.prototype.replace()

  'a1b1c1'.replace('1',2)  -->‘a2b1c1’,並不是期望

  ‘a1b1c1’.replace(/1/g,2)-->'a2b2c2'

  三種引數:

    replace(str,replaceStr);

      replace(reg,replaceStr);

    replace(reg,function); //處理更加複雜的替換結果

    採用第三種,用function的返回值作為替換結果,function會在每次匹配替換結果的時候執行四個引數

    1、匹配字串

    2、正則表示式分組內容,沒有分組則沒有引數

    3、匹配項在字串中的index下標

    4、原字串

    將'a1b2c3d4e5' ---> 'a2b3c4d5e6'  

    

從上看到,兩次匹配的結果分別是 1b2 和 2d4,由於分組後,只對group1和group3保留,去掉group2,因此1b2-->12   3d4-->34,最終替換的結果就是a12c34e5