精通Regex(JavaScript)

來源:互聯網
上載者:User

  在上一篇精通Regex(正則引擎)中大概的講解了一下正則引擎的相關知識,瞭解了它的匹配原理,接下來我們在js這門語言裡面來詳細的使用一下。

  在js中常用於字串處理、表單驗證、處理DOM模型、純編程邏輯等。js中的Regex使用方式提供了兩種:普通方式;建構函式方式。

  普通方式

  普通方式:var reg=/運算式/附加參數
  運算式:一個字串,代表了某種規則,其中可以使用某些特殊字元來代表特殊的規則。
  附加參數:用來擴充運算式的含義,目前主要有三個參數:
    g:代表可以進行全域匹配。
    i:代表不區分大小寫匹配。
    m:代表可以進行多行匹配。
  上面三個參數可以任意組合,代表符合含義,當然也可以不加參數。
  例如:
    var reg1=/[0-9]*b/;
    var reg2=/[a-z]+f/g;
    var reg3=/^[a-z]/i;
    var reg4=/^[a-z]/gm;

  建構函式方式 

  建構函式方式:var reg=new RegExp(“運算式”,”附加參數”);
  其中的運算式和附加參數和普通方式一樣。
  例如:var reg1=new RegExp(“a|b”);
    var reg2=new RegExp(“[a-z]$”,”i”);

  普通方式的的運算式必須是一個常量字串,而建構函式中的運算式可以是常量字串,也可以是一個js變數,例如:
    var value=“abc”;
    var reg=new RegExp(value,”i”);

  如下為js的其他部分元字元:

  1、運算式操作

  1.1exec

  exec(str),返回str中與運算式相匹配的第一個字串,而且以數組的形式表現,當然如果運算式中含有捕捉用的小括弧,則返回的數組中也可能含有()中的匹配字串,例如:
    var regx=/\d+/;
    var rs=regx.exec(“3432ddf53”);
  返回的rs值為:{3432}
    var regx2=new RegExp(“ab(\d+)c”);
    var rs2=regx2.exec(“ab234c44”);
  返回的rs值為:{ab234c,234}

  另外,如果有多個合適的匹配,則第一次執行exec返回一個第一個匹配,此時繼續執行exec,則依次返回第二個第三個匹配。例如:
    var regx=/user\d/g;
    var rs=regx.exec(“ddduser1dsfuser2dd”);
    var rs1=regx.exec(“ddduser1dsfuser2dd”);
  則rs的值為{user1},rs的值為{user2},當然注意regx中的g參數是必須的,否則無論exec執行多少次,都返回第一個匹配  

View Code

  1.2test 

  test(str),判斷字串str是否匹配運算式,返回一個布爾值。例如:
    var regx=/user\d+/g;
    var flag=regx.test(“user12dd”);
  flag的值為true。

View Code

            var reg=/user\d+/g;            var result1=reg.test("uuser12f");            var result2=reg.test("user");            document.write(result1+" "+result2);

  1.3match 

  match(expr),返回與expr相匹配的一個字串數組,如果沒有加參數g,則返回第一個匹配,加入參數g則返回所有的匹配 例子:
    var regx=/user\d/g;
    var str=“user13userddduser345”;
    var rs=str.match(regx);
  rs的值為:{user1,user3} 

View Code

            var reg1=/user\d+/;            var reg2=/user\d+/g;            var str="user12uerdduser33";            var result1=str.match(reg1);            var result2=str.match(reg2);            document.write(result1+" "+result2);

  1.4search 

  search(expr),返回字串中與expr相匹配的第一個匹配的index值。 例子:
    var regx=/user\d/g;
    var str=“user13userddduser345”; var rs=str.search(regx);
  rs的值為:0

View Code

            var reg1=/user\d+/g;            var str="yyuser12uerdduser33";            var result1=str.search(reg1);            document.write(result1);

  1.5replace 

  replace(expr,str),將字串中匹配expr的部分替換為str。另外在replace方法中,str中可以含有一種變數符號$,格式為$n,代表匹配中被記住的第n的匹配字串(注意小括弧可以記憶匹配)。 例子1:
    var regx=/user\d/g;
    var str=“user13userddduser345”;
    var rs=str.replace(regx,”00”);
  rs的值為:003userddd0045 

  例子2:
    var regx=/u(se)r\d/g;
    var str=“user13userddduser345”; var rs=str.replace(regx,”$1”);
  rs的值為:se3userdddse45 

  對於replace(expr,str)方法還要特別注意一點,如果expr是一個運算式對象則會進行全域替換(此時運算式必須附加參數g,否則也只是替換第一個匹配),如果expr是一個字串對象,則只會替換第一個匹配的部分,例如:
    var regx=“user”;
    var str=“user13userddduser345”;
    var rs=str.replace(regx,”00”);
  rs的值為: 0013userddduser345

View Code

            var reg=/(user)\d+/g;            var str="yyuser12uerdduser33";            var result=str.replace(reg,"$1"+"007");            document.write(result);

  對於replace(expr,str)的方法還有一點比較重要,這裡的str可以使字串,也可以是一個函數。我們先來看一個例子: 

View Code

        function init()        {            var reg=/(use)(r)\d+/g;            var str="yyuser12uerdduser33";            var result=str.replace(reg,replaceFunction);            document.write(result);        }        function replaceFunction()        {            var args=arguments;            return args[0];        }

  你可以調試一下,發現裡面的arguments這個維數組(嚴格意義上來說不是數組)如:

  

  第一個元素是我們匹配成功的字串,倒數第一個是我們需要匹配的完整的字串,倒數第二個表示此次匹配成功的位置(一個字串的第0個位置是第一個字母的前面,第1個位置是第1個字母和第2個字母之間,一次類推),中間的數量會右邊變,代表你的Regex裡面記錄的資料,也就是括弧()裡面的資訊,我這裡有(use)和(r),所以剛好對應。

  其實參數為函數的時候就是代表正則引擎將匹配的部分過程開放出來了,讓我們可以控制一部分操作,這個方法的目的是捕獲引擎匹配成功時的狀態,然後把所有資料通過arguments開放出來,並且有使用者自己定義是否需要將這些匹配成功的資料替換成為別的,My Code裡面return的是第一個元素,也就是本身,所以最後結果不會改變,而且由於我的運算式使用了g(全域匹配),所以你會發現還會第二次進入這個函數,第二次匹配的就是user33。由此我們發現了參數為函數時的強大功能,我們可以捕獲引擎匹配成功的每一個狀態,並且可以將這些匹配成功的資訊修改為我們自己想要的。相比傳遞字串參數來的更靈活。方法自己的參數你也可以自己設定,稍微熟悉js文法的朋友都知道,你的function有幾個參數,肯定是一次對應arguments裡面的資料的,再次就不多講了。

  1.6split 

  split(expr),將字串以匹配expr的部分做分割,返回一個數組,而且運算式是否附加參數g都沒有關係,結果是一樣的。 例子:
    var regx=/user\d/g;
    var str=“user13userddduser345”;
    var rs=str.split(regx);
  rs的值為:{3userddd,45}

View Code

            var reg=/user\d/g;            var str="yyuser12uerdduser33";            var result=str.split(reg);            document.write(result);

  2、運算式相關屬性

  2.1lastIndex  

  lastIndex,返回開始下一個匹配的位置,注意必須是全域匹配(運算式中帶有g參數)時,lastIndex才會有不斷返回下一個匹配值,否則該值為總是返回第一個下一個匹配位置,例如:     var regx=/user\d/;
    var rs=regx.exec(“sdsfuser1dfsfuser2”);
    var lastIndex1=regx.lastIndex; rs=regx.exec(“sdsfuser1dfsfuser2”);
    var lastIndex2=regx.lastIndex; rs=regx.exec(“sdsfuser1dfsfuser2”);
    var lastIndex3=regx.lastIndex;
  上面lastIndex1為0,第二個lastIndex2也為0,第三個也是0;如果regx=/user\d/g,則第一個為9,第二個為18,第三個為0。

View Code

            var regx=/user\d/g;            var rs=regx.exec("sdsfuser1dfsfuser2");            var lastIndex1=regx.lastIndex;            rs=regx.exec("sdsfuser1dfsfuser2");            var lastIndex2=regx.lastIndex;            rs=regx.exec("sdsfuser1dfsfuser2");            var lastIndex3=regx.lastIndex;            document.write(lastIndex1+" "+lastIndex2+" "+lastIndex3);

  2.2source 

  source,返回運算式字串自身。例如:
    var regx=/user\d/;
    var rs=regx.exec(“sdsfuser1dfsfuser2”);
    var source=regx.source;
  source的值為user\d

  2.3index  

  index,返回當前匹配的位置。例如:
    var regx=/user\d/;
    var rs=regx.exec(“sdsfuser1dfsfuser2”);
    var index1=rs.index; rs=regx.exec(“sdsfuser1dfsfuser2”);
    var index2=rs.index;
    rs=regx.exec(“sdsfuser1dfsfuser2”);
    var index3=rs.index;
  index1為4,index2為4,index3為4,如果運算式加入參數g,則index1為4,index2為13,index3會報錯(index為空白或不是對象)。

  2.4input

  input,用於匹配的字串。例如:
    var regx=/user\d/;
    var rs=regx.exec(“sdsfuser1dfsfuser2”);
    var input=rs.input;
  input的值為sdsfuser1dfsfuser2。

  2.5[0]

  [0],返回匹配結果中的第一個匹配值,對於match而言可能返回一個多值的數字,則除了[0]外,還可以取[1]、[2]等等。例如:
    var regx=/user\d/g;
    var rs=regx.exec(“sdsfuser1dfsfuser2”); var value1=rs[0];            rs=regx.exec(“sdsfuser1dfsfuser2”);
    var value2=rs[0];
  value1的值為user1,value2的值為user2

  3實戰

  3.1  

  請將下面的字串轉換為對應的字串:(我們公司一個面試題)
    t0.supermap.com/tiles/4/3/2.png
    t4.supermap.com/tiles/m4/4/3.jpg
    a7.supermap.com/tiles/5/m4/6.png
  轉換為對應的
    m0.iclient.com/tiles.png?x=4&y=3&z=2
    m4.iclient.com/tiles.jpg?x=m4&y=4&z=3
    m7.iclient.com/tiles.png?x=5&y=m4&z=6

   答案(不止一個,這隻是其中一個):

View Code

            var regx=/^[a-z]([0-9]\.)supermap(\.com\/tiles)\/([a-z0-9]+)\/([a-z0-9]+)\/([a-z0-9]+)\.(png|jpg)$/;            var str1="t0.supermap.com/tiles/4/3/2.png";            var str2="t4.supermap.com/tiles/m4/4/3.jpg";            var str3="a7.supermap.com/tiles/5/m4/6.png";            var str="m"+"$1"+"iclient"+"$2"+"."+"$6"+"?x="+"$3"+"&y="+"$4"+"&z="+"$5";            var result1=str1.replace(regx,str);            var result2=str2.replace(regx,str);            var result3=str3.replace(regx,str);            document.write(result1+" "+result2+" "+result3);

  另一個答案,一個回複的朋友提的建議:

View Code  

  3.2

  前幾天遇到一個朋友在群裡面問一個問題:他有形如:"[{chk:'-15-13-2-5-'},{chk:'-1-13-4-5-2-'},{chk:'-1-2-5-'}]"這樣的很長的字串資料,在介面使用者選擇了"-5-"、"-2-"等裡面的若干個,那麼希望擷取出"{chk:'...'}"這樣的資料,裡面必須同時存在使用者選擇的所有選項。不如使用者在介面勾選了"-5-"和"-4-",那麼最後只有{chk:'-1-13-4-5-2-'}滿足條件。

  答案: 

View Code

            //此數組為使用者介面選擇的選項組合而成,不可為空            var strArray=["-5-","-4-"];            var str="";            //進行組合部分Regex,這裡的運算式組合為只要包含數組裡面的元素就取出來            for(var i=0;i<strArray.length;i++)            {                if(strArray.length==1)                {                    str=strArray[0];                }                else                {                    if(i==0)                    {                        str+="(?:"+strArray[0];                    }                    else if(i==strArray.length-1)                    {                        str+="|"+strArray[i]+")";                    }                    else                    {                        str+="|"+strArray[i];                    }                }            }            //組合完整的運算式            str="(\\{chk:'[-\\d]*"+str+"[-\\d]*'\\})";            //使用者的字串資料            var myData="[{chk:'-15-13-2-5-'},{chk:'-1-13-4-5-2-'},{chk:'-1-2-5-'}]";            var rexg = new RegExp(str,"g");            //返回包含使用者選擇的條件的所有資料            var array=myData.match(rexg);            var arrayLast=[];            var count=0;            //迴圈遍曆,抽取出滿足使用者選擇所有條件的資料            for(var j=0;j<array.length;j++)            {                for(var k=0;k<strArray.length;k++)                {                    var re=new RegExp("(\\{chk:'[-\\d]*"+strArray[k]+"[-\\d]*'\\})","g");                    if(!re.test(array[j]))                    {                        break;                    }                    else                    {                        if(k==strArray.length-1)                        {                            arrayLast[count++]=array[j];                        }                    }                }            }            alert(arrayLast);

  希望對大家有所協助吧!

 

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.