正則表達式

 

正則表達式對象:javascript

  RegExp對象表示正則表達式,他是對字符串執行模式匹配的強大工具。java

建立正則表達式的方式:正則表達式

  • 經過字面量的方式建立(隱式建立Reg對象) var  re = /pattern/[flag]
    • 說明:pattern是必須的,是咱們要匹配的內容,也就是建立的規則,而flag是無關緊要,根據具體需求添加。
    • flag--》有幾種選擇:
      • i 忽略大小寫->ignore case        默認是大小寫敏感
      • g 全局匹配->global    默認是搜索到第一個匹配就中止 
      • m 多行匹配-> multiple line       默認是單行匹配
    • var re = /\ba\b/g; --全局匹配,以字母a開頭,以字母a結尾
  • 經過構造函數建立正則表達式(顯示建立RexExp對象)        var re = new RegExp("pattern","[flag]");  
    • 如 var re = new RegExp("\d","g");  全局匹配數字
    • 如:var re = new RexExp("\ba\b","g");  全局匹配,以字母a開頭,以字母a結尾

 RegExp對象方法:數組

    • exec()方法
    • test()方法

-----------------------------------------------分隔符-------------------------------------------------函數

String 對象與正則表達式有關的方法:工具

這四個方法是屬於String對象的,不是屬於RegExp對象的測試

 

str.search(s)用於檢測子字符串,若是s存在與str串中,就是匹配到了,返回第一個匹配的結果,若是有多個s,也只返回第一個被匹配到的index(index從0開始計數)this

 search()方法,若是沒有匹配到,就返回-1spa

search()方法不執行全局匹配,它將忽略標誌g,而且老是從字符串的開始位置進行檢索3d

var s = "1234567891"; console.log(s.search("1"));       //0 index是0
console.log(s.search(/1/));       // 0
console.log(s.search(/1/g));     //0 忽略g

 

 

match()方法--》將檢索字符串,以找到一個或多個與regExp匹配的文本 ; regExp是否具備g標誌,對結果是有影響的。

 非全局調用,它的lastIndex也不起做用,爲0.

 

全局調用的狀況下,match的方法中沒有index屬性,若是你去打印,會返回undefined,而lastIndex依舊爲0.

 

'a,b,c,d'.split(,);  寫成這樣,它會嘗試將它轉換爲'a,b,c,d'.split(/,/);

 split還能夠傳入更爲複雜的正則進行字符串的切割。

 

 

 

 

這個參數的位置是固定的,第一個參數是固定的;第二個參數若是有分組,那就是分組的內容,有幾個分組,就是幾個參數;若是第二個沒有分組,第三個參數就是第二個形參,index是每次匹配結果的位置;第四個是每次匹配的字符串的內容,由於在回調函數中,每次回調,都會改變第四個參數的值。

用function返回的值做爲替換的結果

"a1b2c3d2".replace("2","哈"); //"a1b哈c3d2" "a1b2c3d2".replace(2,"哈"); //"a1b哈c3d2" //上面直接寫2,它會隱式的換成/2/ "a1b2c3d2".replace(/2/,"哈"); //"a1b哈c3d2" "a1b2c3d2".replace(/\d/,"哈"); //"a哈b2c3d2" //一次性匹配多個數字,而且替換 "a1b2c3d2".replace(/\d/g,"哈"); //"a哈b哈c哈d哈" 

 

"a1c2ded3r4a3".replace(/\d/g,function(match,index,origin) { console.log("匹配字符串:"+match+"\t"+"index:"+index + "\t"+"原字符串:"+origin); return parseInt(match)+1; });

 

 

用function返回的值做爲替換的結果

------------------------------------------------分隔符-------------------------------------------------

正則表達式由2種基本組成

  原義文本字符 例如: a c d se  e等

  元字符

    元字符是在正則表達式中有特殊含義的非字母字符

      例如: * + ? ~ ^ . | \ ( ) { } [ ] 這些都是有含義的 

      [abc]    -->   表示匹配的字符是a或者 b 或者c  

      [^abc]  -->   表示匹配的字符不包含a 或者b或者c                  

        匹配小寫字母a-z   [a-z]

          大寫字母A-Z  [A-Z]    

          匹配0-9,a-z,A-Z     [0-9a-zA-Z] 

     日期: 2017-5-31  若是想匹配中間的橫線  /[0-9-]/

       var date = "2017-5-21".replace(/[0-9-]/g,"A");    --->  AAAAAAAAA

       將中間的橫線替換掉   var date = "2017-5-21".replace(/-/g,"/");     ---> 2017/5/21

       var date = "2016-3-3".replace(/0-9/g,"A");      -->AAAA-AA-AA

--------------------------分割線-------------------------------------------------------------------  

 

\t 水平製表符
\v 垂直製表符
\r 回車符
\n 換行符
\o 空字符
\f 換頁符
\cX 與X對應的控制字符(ctrl+x)

 

 

 

 

 

 

 

 

 

 

    等價於
. 除了回車符和換行符的全部字符 [^\n\r]
\d 數字字符 [0-9]
\D 非數字字符 [^0-9]
\s 空白符 [\t\n\v\f\r]
\S 非空白符 [^\t\n\v\f\r]
\w 單詞字符,數字,下劃線 [a-zA-Z0-9_]
\W 非單詞字符 [^a-zA-Z0-9_]

 

 

 

 

 

 

 

 

 

 

 

 

測試上面的.這個  這是不能匹配到回車和換行符

如今來試試空白符   空白符被替換了

 

 

測試\s 空白符  藍色部分有一個空格,裏面和\s等價的都被替換了,空格也被替換了

 測試\w -->單詞字符,數字,下劃線     正常的匹配到了,除了空格,逗號,點等一些符號,應該還有其餘的不會被匹配到好比分好,冒號等

如今是\W --》非單詞字符   《==》  [^0-9a-zA-Z]    漢字也被匹配到了

下面的示例是如何只匹配單個漢字

漢字的字符在  [\u4e00-\u9fa5]之間

若是漢字被包裹在一些字符中間,咱們若是連那些字符也要一塊兒匹配的話,就須要像下面那樣進行轉義

 

邊界
^ 以什麼開頭
$ 以什麼結尾
\b 單詞邊界
\B 非單詞邊界

 

 

 

 

 

 

量詞
次數出現0次或者1次(最多出現1次)
+ 出現1次或屢次(最少出現1次)
* 出現0次或屢次(任意次數)
{n} 出現n次
{n,m} 出現n到m次   {1,5} 出現1到5次,包含1和5
{n,} 至少出現n次以上    {2,}  至少2次以上
?=n 匹配任何其後緊接指定字符串 n 的字符串。
!?n 匹配任何其後沒有緊接指定字符串 n 的字符串。

 

 

 

 

 

 

 

 

 

正則表達式的前瞻:

  正則表達是從文本頭部向尾部開始匹配,文本尾部的方向稱爲前。前瞻就是正則表達式匹配到規則的時候,向前檢查是否符合斷言 (斷言就是前瞻語法的一部分)

  符合和不符合特定的斷言稱爲確定/正向匹配和否認/負向匹配 

    前瞻和後顧方向相反,javascript不支持後顧,因此不做說明。

正則表達式
名稱 正則表達式   含義
正向前瞻 exp(?=n) 量詞匹配任何其後緊接指定字符串 n 的字符串。 javascript支持
負向前瞻 exp(!?n) 量詞匹配其後沒有緊接指定字符串 n 的任何字符串。
正向後顧  exp(?<=assert)   javascript不支持
負向後顧 exp(?<!=assert)   

 

 

 

 

 

 

  

var s = "asdf2e2ed"; //括號裏面是斷言部分,不會替換
console.log(s.replace(/\w(?=\d)/g,"換")); //結果: "asd換2換2ed"

//對其後緊跟 "all" 的 "is" 進行全局搜索:

var str="Is this all there is";
var patt1=;/is(?= all)/g
 //因此is被匹配到

 "a2c3deda#v@".replace(/\d(?=\w)/g,"是");  //前瞻
   //   結果     "a是c是deda#v@"

 

第一個是前瞻,就是要求王武的前面必須是張二,符合條件,將張二替換掉,而王武只是斷言,不會被替換

第二個是後瞻,要求張二的後面不能是王武,符合條件,將張二替換掉。 

 

 

分組

  用()能夠到達分組的目的,例如:可使量詞做用於分組

  若是不分組,量詞只做用於離它最近的內容

   情景假設:要匹配某個一單詞連續出現3次,該如何寫正則表達式?

上面這個作法是不對的,緣由是量詞3次是隻做用在d上面,因此返回false

下面就是運用分組,將整個目標包裹起來,讓量詞做用於分組

  情景模擬:第一個是字母,緊跟這是2個數字的一個字符串

 

 正則表達式中的  或 |

 

 下面的是用[]來表示

 

分組中的反向引用

 有分組纔有反向引用,它的表示方式是$  ,單純的$在沒有分組的狀況下,是表示以什麼結尾

//年-月-日
var s2 = "2017-05-12"; //目標:月-日-年
console.log(s2.replace(/(\d{4})-(\d{2})-(\d{2})/g,"$2-$3-$1")); //結果:"05-12-2017"

 

讓日期 不區分-和/

//年-月-日
var s2 = "2017-05-12"; var s3 = "2017/05/12"; //目標:月-日-年
console.log(s2.replace(/(\d{4})[-/](\d{2})[-/](\d{2})/g,"$2-$3-$1")); //"05-12-2017"
console.log(s2.replace(/(\d{4})[-/](\d{2})[-/](\d{2})/g,"$2-$3-$1")); //"05-12-2017"

 

 忽略分組:當不但願捕獲某個分組時,只須要在分組(   後面加?:便可

此時,不能再寫$3,由於$3不存在,$2對應的是12,$1對應的是2017

 

 

--------------------------------分割線------------------------------------

正則表達式的貪婪模式(針對量詞而言的模式):

  它會盡量多的去匹配,因此會以3位爲基準,進行替換

  

 

 

正則表達式的非貪婪模式(針對量詞而言的模式):
  它會盡量少的去匹配,也就是說,一旦匹配成功,它不會再繼續嘗試匹配

  作法:在量詞後面加?

  這裏,就是以2位爲基準,進行替換,它不會再嘗試以3位爲基準的這個狀況

 

RegExp 對象屬性

RegExp 對象方法

 

注意:

var reg = /\w/;

console.log(reg.test("s"));  //true
console.log(reg.test("s"));  //true    
console.log(reg.test("s"));  //true

 

 

var reg = /\w/g; console.log(reg.test("a")); //true
console.log(reg.test("a")); //false
console.log(reg.test("a")); //true

 

出現上面那種狀況的緣由:是lastIndex在做怪,lastIndex受到了影響

lastIndex:當前匹配結果的  最後一個字符  的  下一個字符的位置

var reg = /\w/; while(reg.test("ab")) { console.log(reg.lastIndex); } //1 //2

 

上面while先匹配a,即a就是匹配的結果,而a就一個字符,它也會死最後一個字符,a的下一個字符就是b,因此lastIndex先返回位置1。

此時,將上次匹配的結果(位置)記住了,而後往下繼續找

同理:b是當前匹配的結果,b也是最後一個字符,b的下一個位置就是2,因此lastIndex返回位置2

到第3次循環的時候,後面沒有內容了,lastIndex又被重置爲0,而0在js中表明false,因此第三次循環就直接退出去了。

 

對於reg.test("ab");一下子出現true,一會出現false的狀況,有一種不是特別好的辦法來解決:

   (/\w/g).test("ab");

這種方法每次的結果都爲true,可是這種方法的原理是:每次都從新實例化一個正則對象,缺點:消耗內存,每次實例化都須要內存開銷,並且不必這樣作,由於test()方法的本意就是測試有沒有這麼一個目標字符串。

用var reg = /\w/;   reg.test("ab");不用加global  它一檢測到a,就返回true,就再也不往下匹配。

 

問題:若是想知道,咱們在一串字符串中的哪一個位置匹配的,就用exec()方法

  exec() 方法的功能很是強大,它是一個通用的方法,並且使用起來也比 test() 方法以及支持正則表達式的 String 對象的方法更爲複雜。

  1. 使用正則表達式對字符串進行搜索,並會更新RegExp對象的屬性(lastIndex) 以反映匹配的結果
  2. 若是沒有匹配到文本,就返回null,不然就返回一個數組

          數組的兩個額外屬性

    • index   聲明匹配文本第一個字符的位置  (計數是從0開始的)
    • input    存放被檢索的字符串string

   匹配過程:

    若是 exec() 找到了匹配的文本,則返回一個結果數組。不然,返回 null。

    此數組的第 0 個元素是與正則表達式相匹配的文本 

    第 1 個元素是與 RegExpObject 的第 1 個子表達式相匹配的文本(若是有的話)

    第 2 個元素是與 RegExpObject 的第 2 個子表達式相匹配的文本(若是有的話)

    以此類推。。。。

 

    咱們能夠看得出,在調用非全局的 RegExp 對象的 exec() 方法時,返回的數組與調用方法 String.match() 返回的數組是相同的。

    在非全局下,exec()方法的lastIndex屬性根本不會生效,始終返回0.

  

    可是,當 RegExpObject 是一個全局正則表達式時,exec() 的行爲就稍微複雜一些。它會在 RegExpObject 的 lastIndex 屬性指定的字符處開始檢索字符串 string。

    當 exec() 找到了與表達式相匹配的文本時,在匹配後,它將把 RegExpObject 的 lastIndex 屬性設置爲匹配文本的最後一個字符的下一個位置。這就是說,您能夠經過反覆調用 exec() 方法來遍歷字符串中的全部匹配文本。當 exec() 再也找不到匹配的文本時,它將返回 null,並把 lastIndex 屬性重置爲 0。

     

var reg = /\d(\w)\d/; var reg2 = /\d(\w)(\w)\d/g; var s = "$ed1se2*d3rw3e4"; var ret = reg.exec(s); //console.log("lastIndex->"+reg.lastIndex+"\t"+ret.toString()+" index->"+ret.index); //console.log("lastIndex->"+reg.lastIndex+"\t"+ret.toString()+" index->"+ret.index);

while(ret=reg2.exec(s)) { console.log("lastIndex->"+reg2.lastIndex+"\t"+ret.toString()+" index->"+ret.index); }

前面2次使用reg再也不全局匹配,lastIndex都爲0,表示不生效。那個e是3e4的子串,若是沒有分組,就沒有這個子串。

 

 提示和註釋

    重要事項:若是在一個字符串中完成了一次模式匹配以後要開始檢索新的字符串,就必須手動地把 lastIndex 屬性重置爲 0。

    提示:請注意,不管 RegExpObject 是不是全局模式,exec() 都會把完整的細節添加到它返回的數組中。這就是 exec() 與 String.match() 的不一樣之處,後者在全局模式下返回的信息要少得多。所以咱們能夠這麼說,在循環中反覆地調用 exec() 方法是惟一一種得到全局模式的完整模式匹配信息的方法。

-----------------------------------------分割線--------------------------------------------------------------------------------------------

 

實例:

匹配ab+數字+任意字符的字符串 reg=/ab\d./ reg=/ab[0-9][^\n\r]/ reg=/ab[0-9]./
2015-12-31 reg=/\d{4}-\d{2}-\d{2}/
將上面的日期換成12-31-2015  "2015-12-31".replace(/(\d{4})[-/](\d{2})[-/](\d{2})/,"$2-$3-$1"));
^表示邊界  str = "aabbe" /^a/.test(str);               返回true
$表示結尾  str = "aabbcc" /c$/.test(str);             返回treu
\b 單詞邊界 var str = "asdasd a"; /\ba\b/g.test(str);           返回true
\B非單詞邊界      
^a$ 以a開頭,a結尾 與/\ba\b/g有點不一樣 若是str = "abcde  a"  那麼/^a$/g 和/\ba\b/g就不一樣 若是 str="a"   那麼兩者結果就相同
var s = "123456789".replace(/\d{2,3}/,"a");  結果"aaa"   --這裏涉及到正則表達式的貪婪模式 儘量多的匹配,因此會以3位爲基準,進行替換
"335a22be".replace(/\d{2,3}?/g,"換");  "換5a換be"   --這裏涉及到正則表達式量詞裏面的非貪婪模式
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息