正则表达式 (英语: Regular Expression, 在代码中常简写为 regex,regexp 或 RE) 使用单个字符串来描述, 匹配一系列符合某个句法规则的字符串搜索模式.
我想正则表达式之所以难, 主要体现在以下几个方面:
1)正则表达式的符号晦涩难懂
2)不支持排版(至少 JavaScript 目前还不支持)
3)不能设置断点, 不能跟踪调试
4)没有真正的标准, 不同工具所支持的正则表达式有许多细节上的差异
正则表达式本质上是一整套的处理字符串的模型, 帮助人们利用简短的表达式来实现复杂的算法. 早期的正则表达式引擎只有三百多行代码, 发展到后来也不到 1 万行代码.
打一个不恰当的比喻, 利用正则表达式处理字符串, 就像是利用 SQL 处理数据. 正如我们在处理数据时要避免使用复杂 SQL, 我们在处理字符串时也应当避免使用复杂的正则表达式.
下面是一段判断 IP 地址合法性的代码, 比单纯用正则表达式要简单:
- 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
浅议正则表达式的执行效率
执行下面这个 JavaScript 的正则表达式, 比较 IE/Safari/Firefox/Chrome 的执行效率, 发现 Safari 和 Firefox 首次打开时较慢但是再刷新可做到瞬间完成, Chrome 和 IE 则是每次打开和刷新都慢, 这说明 JavaScript 在 IE 和 Chrome 上还是完全基于 NFA 算法做优化, Safari 和 Firefox 则可能用到了 DFA 算法(也可能是缓存).
- var p1 = /X(?:.+)+X/;
- iJs.put(p1.exec("=XX=========================="));
正则表达式对象: exec 方法:
如果正则表达式使用了 g 作为后缀, 则会记住上次执行的结果, 执行时会找后面匹配.
如果正则表达式没有使用 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 ------------- 4
正则表达式对象: 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 方法返回一个对象, 需注意如果正则表达式使用了后缀 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 第一个参数输入的是字符串或不带后缀的正则表达式, 则只匹配替换一次.
只有正则表达是带后缀 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 方法类似, 但是接受的是正则表达式对象, 如果能够匹配, 则返回首次匹配的首字符位置, 如果不能匹配, 则返回 - 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
来源: http://www.css88.com/web/javascript/11453.html