javascript之正則表達式總結

来源:http://www.cnblogs.com/venoral/archive/2016/03/07/5243429.html
-Advertisement-
Play Games

瞭解RegExp類型: ECMAScript通過RegExp類型來支持正則表達式。 var expression=/pattern/flags; 正則表達式的模式(pattern)部分: 可以是任何簡單或複雜的正則表達式,可以包含字元類,限定符,分組,向前查找,反向引用。 關於正則表達式中各種特殊字


瞭解RegExp類型

ECMAScript通過RegExp類型來支持正則表達式。 var expression=/pattern/flags;  

正則表達式的模式(pattern)部分

可以是任何簡單或複雜的正則表達式,可以包含字元類,限定符,分組,向前查找,反向引用。 關於正則表達式中各種特殊字元(如 \,^,$,\w,\b 等)的含義可以參考 MDN 正則表達式-特殊字元 的整理。這裡我們簡單介紹一下向前查找和反向引用。

  • 向前查找:正則表達式向前使用一些字元而不移動這些字元的位置,分為正向前預搜索也叫正向肯定查找( x(?=y) )與負向前預搜索也叫正向否定查找( x(?!y) )。
  • 反向引用:標識字元串中可以提供的重覆字元或字元串,可以使用捕獲組反向引用匹配。帶編號的反向引用 \number number是正則表達式中捕獲組的序號位置。
  1. 表達式 \1~\9 解釋為反向引用而不是八進位代碼。 /\b(\w+)\s\1/.exec('s_ s_');//["s_ s_", "s_"]
  2. 如果多位表達式的第一個數字是8或者9(如 \80 或 \91 ),則該表達式將被解釋為文本。 /\b(\w+)\s\80/.exec('s_ 800');//["s_ 80", "s_"]
  3. 對於編號為 \10 或更大值的表達式,如果存在與該編號對應的反向引用,則將該表達式視為反向引用。否則將這些表達式解釋為八進位。
    /(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)xx\10/.exec('12345678910xx10');//["12345678910xx10", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
    /(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)xx\11/.exec('12345678910xx10');//null
  4. 如果捕獲組嵌套捕獲組,捕獲組確定的順序是內部從外到內,外部從左到右。來個代碼體會一下。
    /\b(\w+x(x))\s(\1)/.exec('s_xx s_xxSTOP');//["s_xx s_xx", "s_xx", "x", "s_xx"]
  5. 如果正則表達式包含對未定義的組成員的反向引用,則會發生分析錯誤,根據語言的不同正則表達式引擎將引發 ArgumentEXception 。對於javascript會返回null。/\b(\w+)\s\2/.exec('s_ 8');//null
  • 參考正則表達式中的反向引用構造      正則基礎之反向引用
  • 反向引用實例代碼:捕獲組捕獲到的內容不僅可以在正則表達式外部通過程式進行引用( RegExp.$n )也可以在正則表達式內部進行引用( \number ,這種引用方式就是反向引用)。
    //表達連續三個相同的小寫,{2}應用在\1身上
    /([a-z])\1{2}/.exec('aaa');//["aaa", "a"]
    //一道有意思的正則問題
    /(\w)((?=\1\1\1)(\1))/.exec('aa bbbb');//["bb", "b", "b", "b"]
    
    /*這裡捕獲組有三個,$1為(\w)中的內容,$2為((?=\1\1\1)(\1))中的內容:
    需註意(?=\1\1\1)並不是捕獲組而是正則表達式的判斷條件,x(?=y)表示匹配x僅僅當後面跟著y,判斷條件並不是匹配結果的一部分。所以現在$2的內容為(\1)即‘b’。$3就是\1的內容。返回的匹配項
    “bb”中的第一個'b'為"aa bbbb"中的第一個'b',第二個'b'為"aa bbbb"中的第二個'b'。*/
    
    /(\w)(x(?=\1\1\1)(\1))/.exec('aa bxbbbcb');//["bxb", "b", "xb", "b"]
    //這裡$2的內容為(x(?=\1\1\1)(\1))中的內容即x(\1);
    
    //其實上面兩種模式可以簡化成/(\w)(?=\1\1\1)(\1)/表示匹配\w僅當該\w後後面跟著三個\1,然後獲取的匹配項為該\w且其後再緊跟著\1的字元串。同理/(\w)x(?=\1\1\1)(\1)/
    /(\w)((?=\1\1\1)(\2))/.exec('aa bbbbv');//["b", "b", "", ""]
    /*捕獲組$2為((?=\1\1\1)(\2))中的內容,由於此時還未執行完捕獲組$2處的匹配,所以\2表示""。$3即為\2的內容還是""。所以這條匹配被解釋為返回\w且其後緊跟3個該\w的字元串,返回\w+''就只返回'b'了。*/

正則表達式的標誌位(flags)部分:

可以帶有一個或多個標誌,用以表明正則表達式的行為。

  1. g:表示全局模式,模式將被應用於所有字元串,而非在發現第一個匹配項時立即停止。 'cat mat bat'.replace(/.(?=at)/g,'A');//"Aat Aat Aat" 
  2. i:不區分大小寫模式,在確定匹配項時忽略模式與字元串的大小寫。 'cAt mat bAt'.replace(/a/gi,'B');//"cBt mBt bBt" 
  3. m:多行模式,在到達一行文本末尾時還會繼續查找下一行中是否存在與模式匹配的項。
    var str='cat\nmat\nbat';
    str.replace(/at/gm,'AB');
    /*"cAB
    mAB
    bAB"*/

正則表達式中的元字元部分:

在模式中使用這些元字元時必須轉義,如果想要匹配的字元串中包含這些字元,就需要對他們進行轉義。

  • ( [ { \ ^ $ | ) ? * + . ] }
    //匹配"[bc]at"
    /\[bc\]at/.exec("xx[bc]at");//["[bc]at"]
    
    //匹配".at"
    /\.at/.exec("xx.at");//[".at"]

 

創建正則表達式

  • 字面量形式 :形如 var expression=/pattern/flags; 
  • RegExp構造函數:兩個參數(要匹配的字元串模式,可選的標誌字元串),不能把正則表達式字面量傳遞給構造函數,雖然即使這樣寫了也不會報錯。可以使用字面量定義的任何表達式都可以使用構造函數來定義。如下:
    var p=/[bc]at/;
    new RegExp('[bc]at');// /[bc]at/
  1. 當不傳任何參數或參數一為空字元串時, new RegExp();// /(?:)/  或 new RegExp('');// /(?:)/ ,表示匹配 "" 但不記住匹配項( "" 其實就是 ":" 之後的空串,不記住x匹配項的規則為(?:x)),所以在匹配任何字元串時都返回 [""] 。所以由此可以猜想一下javascript正則引擎內部機制應該是預設匹配 "" 且不記住該匹配項,除非顯式聲明在 ":" 之後的需要匹配的字元串,加上 "(?:)" 顯式聲明不記住匹配項。
  2. 由於構造函數模式參數是字元串,所以某些情況下(是指那些已經轉義過的字元)對字元進行雙重轉義(即在字面量形式的單重轉義再來一層轉義)。某些情況下當然也可以進行單重轉移( new RegExp('\w');// /w/ )。註意'\'比較特殊,在字元串中也需要進行轉義。
    var p=/\\n/;//轉義\,字元"\"在字元串中常需要被轉義為"\\"
    p.exec("\\nxx");//["\n"]
    
    var p=new RegExp("\\\\n");// /\\n/ 如果想獲得正則表達式字面量為/\\n/,需要在正則表達式中再來一層轉義
    p.exec('\\nxx');//["\n"] 註意被匹配的字元串'\nxx'中\n的\也被轉義了
    
    new RegExp('\\n').exec("\n");// 
    ["
    "]
    /*RegExp('\\n')返回/\n/,即意思匹配換行符*/
    
    new RegExp('\n').exec("\n");//
    ["
    "]
    /*new RegExp('\n')返回
    /
    / ,表示並沒有進行轉義,而是返回字面量
    /
    /,意思匹配換行符
    */
  3. 下麵給出一些單重,雙重轉義模式的參考:第幾次轉義在表中已標出,單代表第一次轉義,雙代表在已經有的轉義的基礎上再進行的轉義。
    字面量模式 等價的字元串
    /\[bc\]at/ "\\[bc\\]at"
    /\.at/ "\\.at"
    /name\/age/ "name\\/age"
    /\d.\d{1,2}/   "\\d.\\d{1,2}" 單
    /\w\\hello\\123/ "\\w\\\\hello\\\\123" 單+雙

RegExp的實例屬性: 

通過實例的屬性可以獲取有關模式的各種信息

  •  global :布爾值,表示是否設置了g標誌。
  •  ignoreCase :布爾值,表示是否設置了i標誌。
  •  multiline :布爾值,表示是否設置了m標誌。
  •  lastIndex :整數,表示開始搜索下一個匹配項的字元位置,從0算起。前提是設置g標誌時才會有用。
  •  source :正則表達式的字元串標誌,按照字面量形式而非構造函數中的字元串模式返回字元串
    new RegExp('\\\\w');// /\\w/ 返回自面量形式正則表達式
    new RegExp('\\\\w').source;// "\\w" 字元串

RegExp的實例方法:

  • exec():該方法是專門為捕獲組而設計的,參數為要匹配的字元串,返回包含第一個匹配項信息和可能有的捕獲組的數組,若未匹配到返回 null 。(返回的雖然是 Array 的實例,但還包含兩個額外的屬性: index 表示匹配項在字元串中的位置, input 表示應用正則表達式的字元串)
    var arr=new RegExp('\\\\(w)').exec('\\w');// ["\w", "w"]
    arr;// ["\w", "w"]
    arr.index;//0
    arr.input;// "\w" 即exec()里的內容

    exec() 和 match() 方法的區別:

  1. 對於 exec() 而言,即使在模式中設置了全局標誌g,它每次也只返回一個匹配項;字元串的 match() 方法在設置g的時候可以返回全部匹配項而沒有捕獲組且返回的數組沒有index和input屬性。

  2. 對於exec()而言可以返回捕獲組,但match()在沒有全局g標誌時才能返回捕獲組,此時match()返回的數組有index和input屬性。

    //返回全局匹配項演示比較
    var arr='ababcdab'.match(/ab/g);// ["ab", "ab", "ab"]
    arr.index; // undefined
    arr.input; // undefined
    /ab/g.exec('ababcdab');// ["ab"]
    
    //捕獲組演示比較,match()方法和有無設置全局g標誌有關
    'ababcdab'.match(/a(b)/g);// ["ab", "ab", "ab"]
    var arr='ababcdab'.match(/a(b)/);// ["ab", "b"]
    arr.index;// 0
    arr.input;// 'ababcdab'
    /a(b)/g.exec('ababcdab');// ["ab", "b"]  
  3. 所以在選擇使用方法的時候要先考慮好側重該方法的哪方面功能,在不設置全局標誌g的情況下,在同一個字元串上多次調用exec()則總是返回第一個匹配項的信息,而在設置全局標誌的情況下,每次調用exec()則都會在字元串中沿著上次查找的位置往後繼續查找新的匹配項。

    //未設全局,每次從頭開始查找
    var p=/a/;
    var str='ababa';
    var a=p.exec(str);// ["a"];
    var b=p.exec(str);// ["a"];
    a==b;// false
    a.index==b.index;// true
    
    //設置全局,沿著上次位置繼續查找新匹配
    var p=/a/g;
    var str='ababa';
    var a=p.exec(str);// ["a"]
    a.index;// 0
    var b=p.exec(str);// ["a"]
    b.index;// 2
  • test():接收字元串參數,在模式與字元串參數匹配情況下返回 true ,否則返回 false 。常被用在 if() 中當判斷條件。
    var text="000-000-000";
    var p=/((\d{3})-)\1*\2/; if(p.test(text)){
      console.log('匹配成功');
    }
  •  RegExp 實例繼承 Object 的 toLocaleString() 和 toString() 方法都會返回正則表達式的字面量形式的字元串,與如何創建正則表達式的方式無關。 valueOf() 則返回正則表達式字面量本身。
    var p=/\[new\]bi/;
    p.toLocaleString();// "/\[new\]bi/"
    p.toString();// "/\[new\]bi/"
    p.valueOf();// /\[new\]bi/
    
    var p=new RegExp('\\[new\\]bi');
    p.toLocaleString();// "/\[new\]bi/"
    p.toString();// "/\[new\]bi/"
    p.valueOf();// /\[new\]bi/

RegExp的構造函數屬性:

構造函數本身包含一些屬性(靜態屬性),這些屬性適用於作用域中的所有表達式,並且基於所執行的最近一次正則表達式操作而變化。有長屬性名(如下代碼)和短屬性名(即$首碼形式,由於這些符號大多不是有效的ECMAScript標識符,所以不能直接在 RegExp 構造函數上以 "." 的方式訪問,而要通過方括弧語法來訪問)兩種方式訪問這些屬性

  1. /(.)hort/g.exec('this is a short day');// ["short", "s"]
    
    //最近一次要匹配的字元串
    RegExp.input;// "this is a short day"  或RegExp["$_"]訪問;
    
    //最近一次的匹配項
    RegExp.lastMatch;// "short"  或RegExp["$&"]訪問;
    
    //在最近一次要匹配的字元串中的最近一次匹配項之前的文本 
    RegExp.leftContext;// "this is a "  或RegExp["$`"]訪問;
    
    //在最近一次要匹配的字元串中的最近一次匹配項之後的文本 
    RegExp.rightContext;// " day"  或RegExp["$'"]訪問;
    
    //最近一次(最後一次)匹配的捕獲組
    RegExp.lastParen;// "s"  或RegExp["$+"]訪問;

    捕獲組訪問屬性:還有9個用於存儲捕獲組的構造函數屬性,訪問語法是 RegExp.$n ,其中n取值1~9,用於獲取第n個匹配的捕獲組。在調用 exec() , test() 或 match() 等正則系列方法時這些屬性會被自動填充。

    var  text="this is a short summer";
    var pattern =/(..)or(.)/g;
    if(pattern.test(text)){
       console.log(RegExp.$1); // sh
       console.log(RegExp.$2); // t 
    }

模式的局限性:

缺少一些高級正則表達式的特性,如不支持向後查找,命名的捕獲組(形如 \k<name> 引用之前名為 name 的捕獲組的字元串)等。

參考:

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text
  • 在設計的過程中第一步就是先排版構建框架,後利用CSS對各個塊進行定位。不過各個樣式的id和class博客園本身已經定義好了,我們可以在設置面板中勾選禁用模板預設CSS”覆選框。然後刷新博客首頁查看源碼,將代碼copy到dw上修改樣式。最後將自己修改滿意好的css樣式貼到“管理”-“博客設置”中“通過
  • 1.Ajax 1.1.Ajax簡介 Ajax簡介這一部分我們主要是談一下ajax的起源,ajax是什麼?因為這些是跟技術無關的。所以,大多細節都是一筆帶過。 Ajax的起源? Ajax一詞源於2005年 Jesse James Garrett發表的一篇題為"Ajax:A new Approach t
  • 閉包的概念: 在電腦科學中,閉包(也稱詞法閉包或函數閉包)是指一個函數或函數的引用,與一個引用環境綁定在一起。這個引用環境是一個存儲該函數每一個非局部變數(也叫自由變數的表)。已暈^^ 閉包,不同於一般的函數,它允許一個函數在立即詞法作用域外調用時,仍然訪問非本地變數 ——from維基百科 閉包其
  • 背景:在前端開發中,有時會為頁面綁定resize事件,或為一個頁面元素拖拽事件(其核心就是綁定mousemove)在一個正常操作中也有可能在一個短時間內觸發非常多次事件綁定程式,而DOM操作是很消耗性能的,如果為這些事件綁定一些操作DOM節點的操作的話就會引發大量的計算,在用戶看來頁面可能就一時間沒
  • 講述了javascript主要由ECMAScript、DOM、BOM組成
  • 問題1: 使用連續賦值後面的變數會成為全局對象的一個屬性,並且這個屬性可以通過delete刪除。 原因:賦值語句是從右往左執行的,我們將10賦值給了c,但是c此時還聲明,接著把c的返回值賦值給了b,但是b也還沒有聲明,最後賦值給了a此時a有聲明,所以a就是局部變數。 var a = b = c =
  • (第一篇博文) 今天在一個交流群里見他們無聊,然後找到之前收藏的一些c語言題目放出去想讓他們做,結果反倒是自己不會做,於是花了很多時間去想。 原題:張三說李四在說謊,李四說王五在說謊,王五說張三和李四都在說謊。現在問:這三人中到底誰說的是真話,誰說的是假話? 其實問題本身並不難,只是一開始想多了,陷
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...