精通正則表達式(JavaScript)


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

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

  普通方式

  普通方式: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個字母之間,一次類推),中間的數量會右邊變,代表你的正則表達式里面記錄的數據,也就是括號()里面的信息,我這里有(use)和(r),所以剛好對應。

  其實參數為函數的時候就是代表正則引擎將匹配的部分過程開放出來了,讓我們可以控制一部分操作,這個方法的目的是捕獲引擎匹配成功時的狀態,然后把所有數據通過arguments開放出來,並且有用戶自己定義是否需要將這些匹配成功的數據替換成為別的,我的代碼里面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="";
            //進行組合部分正則表達式,這里的表達式組合為只要包含數組里面的元素就取出來
            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);

  希望對大家有所幫助吧!

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM