我想Regex之所以難,主要體現在以下幾個方面:1)Regex的符號晦澀難懂2)不支援排版(至少javascript目前還不支援)3)不能設定斷點,不能跟蹤調試4)沒有真正的標準,不同工具所支援的Regex有許多細節上的差異下文中如涉及Regex符號含義不明,請參閱<<javascriptRegex入門筆記(完整版)>>Regex本質上是一整套的處理字串的模型,協助人們利用簡短的運算式來實現複雜的演算法。早期的Regex引擎只有三百多行代碼,發展到後來也不到1萬行代碼。打一個不恰當的比喻,利用Regex處理字串,就像是利用SQL處理資料。正如我們在處理資料時要避免使用複雜SQL,我們在處理字串時也應當避免使用複雜的Regex。下面是一段判斷IP地址合法性的代碼,比單純用Regex要簡單:var isIPAdress = function(IPStr){ var pttrn = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/; var IPObj = pttrn.exec(IPStr); var bool_result = false; if(IPObj){ //添加進一步的識別規則 if(IPStr==="0.0.0.0"){ bool_result = false; }else if(IPStr==="1.1.1.1"){ bool_result = false; }else if(IPObj[1]>=0 && IPObj[1]<=255 && IPObj[2]>=0 && IPObj[2]<=255 && IPObj[3]>=0 && IPObj[3]<=255 && IPObj[4]>=0 && IPObj[4]<=255){ bool_result = true; }else{ bool_result = false; } } return bool_result; } 調試資訊: isIPAdress("10.1.6.255") true isIPAdress("1.1.1.1") false isIPAdress("10.1.a.255") false淺議Regex的執行效率執行下面這個javascript的Regex,比較ie/safari/firefox/chrome的執行效率,發現safari和firefox首次開啟時較慢但是再重新整理可做到瞬間完成,chrome和ie則是每次開啟和重新整理都慢,這說明javascript在ie和chrome上還是完全基於NFA演算法做最佳化,safari和firefox則可能用到了DFA演算法(也可能是緩衝)。var p1 = /X(?:.+)+X/; iJs.put(p1.exec("=XX==========================")); Regex對象:exec方法:如果Regex使用了g作為尾碼,則會記住上次執行的結果,執行時會找後面匹配。如果Regex沒有使用g作為尾碼,則每次執行的結果相同,都是取第一個匹配上的。如果使用了捕獲型括弧,則匹配結果可通過1/2/3/...尾碼獲得,參見前面給出的判斷IP地址合法性的代碼。var pttrn = /bb/; iJs.showObject(pttrn.exec("abaabbaaa")); iJs.showObject(pttrn.exec("abaabbaaa")); pttrn = /a+/g; iJs.showObject(pttrn.exec("abaabbaaa")); iJs.showObject(pttrn.exec("abaabbaaa")); 調試資訊: [Object] bb |--[string] 0 ------------- bb |--[number] index ------------- 4 |--[string] input ------------- abaabbaaa |--[number] lastIndex ------------- 6 [Object] bb |--[string] 0 ------------- bb |--[number] index ------------- 4 |--[string] input ------------- abaabbaaa |--[number] lastIndex ------------- 6 [Object] a |--[string] 0 ------------- a |--[number] index ------------- 0 |--[string] input ------------- abaabbaaa |--[number] lastIndex ------------- 1 [Object] aa |--[string] 0 ------------- aa |--[number] index ------------- 2 |--[string] input ------------- abaabbaaa |--[number] lastIndex ------------- 4Regex對象:test方法返回true或false var pttrn = /bb/; iJs.pt('pttrn.test("abaabbaaa")'); iJs.pt('pttrn.test("ababab")'); 調試資訊: pttrn.test("abaabbaaa") true pttrn.test("ababab") false字串對象:match方法match方法返回一個對象,需注意如果Regex使用了尾碼g,則捕獲型括弧會失效。var pttrn = /a(b)+/; var pttrn_g = /a(b)+/g; var myStr = "abaabbaaa"; var matchObj = myStr.match(pttrn);//捕獲b var matchObj_g = myStr.match(pttrn_g); //捕獲失效 iJs.pt("pttrn"); iJs.pt("pttrn_g"); iJs.pt("myStr"); iJs.showObject("matchObj"); iJs.showObject("matchObj_g"); 調試資訊: pttrn /a(b)+/ pttrn_g /a(b)+/g myStr abaabbaaa [Object] matchObj |--[string] 0 ------------- ab |--[string] 1 ------------- b |--[number] index ------------- 0 |--[string] input ------------- abaabbaaa |--[number] lastIndex ------------- 2 [Object] matchObj_g |--[string] 0 ------------- ab |--[string] 1 ------------- abb |--[number] index ------------- 3 |--[string] input ------------- abaabbaaa |--[number] lastIndex ------------- 6字串對象:replace方法如果replace第一個參數輸入的是字串或不帶尾碼的Regex,則只匹配替換一次。只有正則表達是帶尾碼g才能替換全部。第二個參數可以是函數,下面的例子中列印了函數接受的參數結構。第一個參數是匹配字串、第二個參數開始是捕獲字串、然後跟著index、最後是字串自己。var myStr = "abaabbaaabbb"; var searchValue = "a"; var searchRegExp = /a+/; var searchRegExp_g = /a+/g; var replaceValue = "X"; iJs.pt("myStr"); iJs.pt("searchValue"); iJs.pt("replaceValue"); iJs.pt("myStr.replace(searchValue,replaceValue)"); iJs.put(""); iJs.pt("myStr"); iJs.pt("searchRegExp"); iJs.pt("replaceValue"); iJs.pt("myStr.replace(searchRegExp,replaceValue)"); iJs.put(""); iJs.pt("myStr"); iJs.pt("searchRegExp_g"); iJs.pt("replaceValue"); iJs.pt("myStr.replace(searchRegExp_g,replaceValue)"); iJs.put(""); var myStr_f = "a2aa22aaa222________"; var searchRegExp_g2 = /(a+)2/g; var args;//全域變數便於iJs1捕獲對象 var replaceFunction = function(a,b){ var slice = Array.prototype.slice; args = slice.apply(arguments); iJs1.showObject("args"); return args[0]+"+"; }; iJs.pt("myStr_f.replace(searchRegExp_g2,replaceFunction)"); 調試資訊: myStr abaabbaaabbb searchValue a replaceValue X myStr.replace(searchValue,replaceValue) Xbaabbaaabbb myStr abaabbaaabbb searchRegExp /a+/ replaceValue X myStr.replace(searchRegExp,replaceValue) Xbaabbaaabbb myStr abaabbaaabbb searchRegExp_g /a+/g replaceValue X myStr.replace(searchRegExp_g,replaceValue) XbXbbXbbb myStr_f.replace(searchRegExp_g2,replaceFunction) a2+aa2+2aaa2+22________補充調試資訊: [Object] args |--[string] 0 ------------- a2 |--[string] 1 ------------- a |--[number] 2 ------------- 0 |--[string] 3 ------------- a2aa22aaa222________ [Object] args |--[string] 0 ------------- aa2 |--[string] 1 ------------- aa |--[number] 2 ------------- 2 |--[string] 3 ------------- a2aa22aaa222________ [Object] args |--[string] 0 ------------- aaa2 |--[string] 1 ------------- aaa |--[number] 2 ------------- 6 |--[string] 3 ------------- a2aa22aaa222________字串對象:search方法search方法和indexOf方法類似,但是接受的是Regex對象,如果能夠匹配,則返回最初相符的首字元位置,如果不能匹配,則返回-1。此方法會忽略g標誌。var myStr = "abaabbaaabbb"; var searchRegExp1 = /aaa/; iJs.pt("myStr.search(searchRegExp1)"); var searchRegExp2 = /aXa/; iJs.pt("myStr.search(searchRegExp2)"); 調試資訊: myStr.search(searchRegExp1) 6 myStr.search(searchRegExp2) -1