理顺 JavaScript (19) - 正则表达式对象 RegExp
建立正则表达式的方法
var p1 = new RegExp("abc", "igm"); var p2 = RegExp("abc", "igm"); var p3 = /abc/igm; //判断是否是正则表达式对象 alert(p1 instanceof RegExp); //true alert(p2 instanceof RegExp); //true alert(p3 instanceof RegExp); //true
正则表达式对象的 5 个属性
var p = /abc/igm; //source: 表达式文本, 只读 alert(p.source); //abc //ignoreCase: 是否有指定 i, 只读; i 表示不不区分大小写 alert(p.ignoreCase); //true //global: 是否有指定 g, 只读; g 表示匹配全部 alert(p.global); //true //multiline: 是否有指定 m, 只读; m 表示多行匹配 alert(p.multiline); //true //lastIndex: 最好一次的匹配位置, 是可读写属性. alert(p.lastIndex); //0; 在匹配之前它肯定是 0
正则表达式对象的 2 个方法之 test
//这个 test 非常简单, 它只能返回 true/false 表示是否找到匹配; 通过它了解不到更多信息 var str, p, b; str = '1:abc;2:Abc;3:aBc;4:abC;5:ABc;6:aBC;7:AbC;8:ABC'; p = /abc/i; b = p.test(str); alert(b); //true; 表示有匹配到 p = /abcdefg/i; b = p.test(str); alert(b); //false; 表示没匹配到 //对 test 来讲, 是否指定 g(全局匹配) 是没有意义的; 因为它有发现就返回.
正则表达式对象的 2 个方法之 exec
//exec 返回的是匹配结果, 是个数组 var str, p, arr; str = '1:abc;2:Abc;3:aBc;4:abC;5:ABc;6:aBC;7:AbC;8:ABC'; p = /abc/i; arr = p.exec(str); alert(arr); //abc //怎么能知道返回的 arr 是个数组, 测试一下: alert(arr instanceof Array); //true alert(arr[0]); //abc //何必要用数组表达? 因为正则表达式中可能会有"子表达式", 譬如: p = /(ab)(c)/i; //子表达式是用 () 区分的, 上面表达式包含两个子表达式; 用于 exec 函数时将返回 length = 3 的数组: //arr[0]: 匹配整个表达式的结果; //arr[1]: 匹配第一个子表达式的结果; //arr[2]: 匹配第二个子表达式的结果... //包含子表达式的例子(继续使用上面的字符串 str) p = /(ab)(c)/i; arr = p.exec(str); alert(arr); //abc,ab,c //遍历这个数组 for (var i=0; i < arr.length; i++) { alert(arr[i]); //abc / ab / c } //这个返回的数组还有两个属性: index(匹配到的内容在字符串中的位置)、input(原始字符串) alert(arr.index); //2; 因为是 0 起, 也就是 3 alert(arr.input); //1:abc;2:Abc;3:aBc;4:abC;5:ABc;6:aBC;7:AbC;8:ABC //如果找不到, exec 会返回 null; 这对继续探讨很有用 p = /abcde/i; alert(p.exec(str)); //null
关于 exec 的全局匹配
//首先, exec 不会像 String.match 那样方便的完成全局匹配; 不过这恰是它的强大之处. //第一个例子没有指定 g; 执行了三次 exec 结果都是一样的 var str, p1, arr; str = '1:abc;2:Abc;3:aBc;4:abC;5:ABc;6:aBC;7:AbC;8:ABC'; p1 = /(ab)(c)/i; arr = p1.exec(str); alert(arr); //abc,ab,c arr = p1.exec(str); alert(arr); //abc,ab,c arr = p1.exec(str); alert(arr); //abc,ab,c alert(p1.lastIndex); //5 //这个例子使用了全局匹配, 结果不一样了; var str, p2, arr; str = '1:abc;2:Abc;3:aBc;4:abC;5:ABc;6:aBC;7:AbC;8:ABC'; p2 = /(ab)(c)/ig; arr = p2.exec(str); alert(arr); //abc,ab,c arr = p2.exec(str); alert(arr); //Abc,Ab,c arr = p2.exec(str); alert(arr); //aBc,aB,c alert(p2.lastIndex); //17 //可以这样遍历所有匹配: var str, p, arr; str = '1:abc;2:Abc;3:aBc;4:abC;5:ABc;6:aBC;7:AbC;8:ABC'; p = /(ab)(c)/ig; while ((arr = p.exec(str)) != null) { alert(arr); //可在此提取子表达式的匹配结果, 这个功能只有 exec 可以. }