JavaScript正则API快速入门笔记(高清带书签).pdf
一、RegExp 对象
1.1 创建对象
1.1.1 直接量语法 /pattern/attributes
如:
var pattern=/^[1-9]\d{4}$/;
1.1.2 构造函数语法 new RegExp(pattern,attributes);
如:
var pattern = new RegExp("^[1-9]\\d{4}$");
【注意】直接量语法不能用引号,构造函数语法需要引号。
var pattern=/^[1-9]\d{4}$/表示pattern 是一个正则表达式对象,而var pattern=”/^[1-9]\\d{4}$/”表示pattern 是一个字符串。
参数说明:
参数pattern 是一个字符串,指定了正则表达式的模式或其他正则表达式。
参数attributes 是一个可选的字符串,包含属性"g"、"i" 和"m",分别用于指定全局匹配、区分大小写的匹配和多行匹配。ECMAScript 标准化之前,不支持m 属性。如果pattern 是正则表达式,而不是字符串,则必须省略该参数。
返回值
一个新的RegExp 对象,具有指定的模式和标志。如果参数pattern 是正则表达式而不是字符串,那么RegExp() 构造函数将用与指定的RegExp 相同的模式和标志创建一个新的
RegExp 对象。如果不用new 运算符,而将RegExp() 作为函数调用,那么它的行为与用new 运算符调用时一样,只是当pattern 是正则表达式时,它只返回pattern,而不再创建一个新的RegExp对象。
抛出异常
SyntaxError - 如果pattern 不是合法的正则表达式,或attributes 含有"g"、"i" 和"m" 之外的字符,抛出该异常。
TypeError - 如果pattern 是RegExp 对象,但没有省略attributes 参数,抛出该异常。
1.2 属性
1.2.1 global 例子
var pattern_g=/\d/g;
var pattern=/\d/;
console.info(pattern_g.global);//true
console.info(pattern.global);//false
1.2.2 ignoreCase 例子
var pattern_i=/\w/i;
var pattern=/\w/;
console.info(pattern_i.ignoreCase);//true
console.info(pattern.ignoreCase);//false
1.2.3 multiline 例子
var pattern_m=/\w/m;
var pattern=/\w/;
console.info(pattern_m.multiline);//true
console.info(pattern.multiline);//false
1.2.4 source 例子
var pattern==/\w+/g;
console.info(pattern.source);//结果为\w+
【提示】该文本不包括正则表达式直接量使用的定界符,也不包括标志g、i、m
1.2.5 lastIndex 例子
var str = "11-22-33-44-55-";
var pattern =/-/g;
while(pattern .test(str)){
document.write("- found. index now at: " + pattern .lastIndex);
document.write("<br />");
}
结果:
- found. index now at: 3
- found. index now at: 6
- found. index now at: 9
- found. index now at: 12
- found. index now at: 15
说明:
该属性存放一个整数,它声明的是上一次匹配文本之后的第一个字符的位置。上次匹配的结果是由方法RegExp.exec() 和RegExp.test() 找到的,它们都以lastIndex 属性所指的位置作为下次检索的起始点。这样,就可以通过反复调用这两个方法来遍历一个字符串中的所有匹配文本。该属性是可读可写的。只要目标字符串的下一次搜索开始,就可以对它进行设置。当方法exec() 或test() 再也找不到可以匹配的文本时,它们会自动把lastIndex属性重置为0。
重要事项:不具有标志g 和不表示全局模式的RegExp 对象不能使用lastIndex 属性。
提示:如果在成功地匹配了某个字符串之后就开始检索另一个新的字符串,需要手动地把这个属性设置为0。
1.3 方法
1.3.1 compile 例子
var data="0-1-22-333-4444-5555";
var pattern=/\d/;
var pattern2=/\d/g;
var result=data.replace(pattern,"*");
document.write("原字符串:"+data+"<br />");
document.write("替换后的字符串:"+result+"<br />");
pattern.compile(pattern2);//也可以写成pattern.compile("\\d","g")
var result1=data.replace(pattern,"*");
document.write("重新编译再替换后的字符串:"+result1+"<br />");
运行结果:
原字符串:0-1-22-333-4444-5555
替换后的字符串:*-1-22-333-4444-5555
重新编译再替换后的字符串:*-*-**-***-****-****
提示:compile()方法用于在脚本执行过程中编译正则表达式,也可用于改变和重新编译正则表达式
1.3.2 exec(String)
返回值
返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回值为null。
说明
exec() 方法的功能非常强大,它是一个通用的方法,而且使用起来也比test() 方法以及支持正则表达式的String 对象的方法更为复杂。如果exec()找到了匹配的文本,则返回一个结果数组。否则,返回null。此数组的第0 个元素是与正则表达式相匹配的文本,第1 个元素是与RegExpObject的第1 个子表达式相匹配的文本(如果有的话),第2 个元素是与RegExpObject的第2 个子表达式相匹配文本(如果有的话),以此类推。除了数组元素和length 属性之外,exec() 方法还返回两个属性。index 属性声明的是匹配文本的第一个字符的位置。input 属性则存放的是被检索的字符串string。我们可以看得出,在调用非全局的RegExp 对象的exec() 方法时,返回的数组与调用方法String.match() 返回的数组是相同的。但是,当RegExpObject 是一个全局正则表达式时,exec() 的行为就稍微复杂一些。它会在RegExpObject 的lastIndex 属性指定的字符处开始检索字符串string。当exec() 找到了与表达式相匹配的文本时,在匹配后,它将把RegExpObject 的lastIndex 属性设置为匹配文本的最后一个字符的下一个位置。这就是说,您可以通过反复调用exec() 方法来遍历字符串中的所有匹配文本。当exec()再也找不到匹配的文本时,它将返回null,并把lastIndex属性重置为0。
例子:
(function(){
var str = "112abc232hello33kitty";
var patt = new RegExp("\\d+[a-z]+","g");
var result;
while ((result = patt.exec(str)) != null) {
document.write("匹配的文本"+result);
document.write(",匹配的位置:"+patt.lastIndex);
document.write("<br />");
}
})();
运行结果:
匹配的文本:112abc,匹配的位置:6
匹配的文本:232hello,匹配的位置:14
匹配的文本:33kitty,匹配的位置:21
patt 没有分组的情况下
patt 添加两个分组后
var patt = new RegExp("(\\d+)([a-z]+)","g");
重要事项:如果在一个字符串中完成了一次模式匹配之后要开始检索新的字符串,就必须手动地把lastIndex属性重置为0。
提示:请注意,无论RegExpObject 是否是全局模式,exec() 都会把完整的细节添加到它返回的数组中。这就是exec() 与String.match() 的不同之处,后者在全局模式下返回的信息要少得多。因此我们可以这么说,在循环中反复地调用exec() 方法是唯一一种获得全局模式的完整模式匹配信息的方法
1.3.3 test 例子
返回值
如果字符串string 中含有与RegExpObject 匹配的文本,则返回true,否则返回false。
说明
调用RegExp 对象r 的test() 方法,并为它传递字符串s,与这个表示式是等价的:(r.exec(s) != null)。
例子:
var str = "112abc232hello33kitty";
var patt1 = new RegExp("\\d+");
var result1=patt1.test(str);//true
var patt2 = new RegExp("world");
var result2=patt2.test(str);//false
1.4 javaScript 字符串对象支持正则表达式的方法
1.4.1 search(regexp)
返回值
stringObject 中第一个与regexp 相匹配的子串的起始位置。
注释:如果没有找到任何匹配的子串,则返回-1。
说明
search() 方法不执行全局匹配,它将忽略标志g。它同时忽略regexp 的lastIndex 属性,并且总是从字符串的开始进行检索,这意味着它总是返回stringObject 的第一个匹配的位
置。
例子:
var str = "112AAB";
var patt1 = /[a-z]+/;
var result1=str.search(patt1);//返回-1
var patt2 = /[a-z]+/i;
var result2=str.search(patt2);//返回3
提示:search()对大小写敏感
1.4.2 match(searchvalue),match(regexp)
返回值
存放匹配结果的数组。该数组的内容依赖于regexp是否具有全局标志g。
说明
match() 方法将检索字符串stringObject,以找到一个或多个与regexp匹配的文本。这个方法的行为在很大程度上有赖于regexp是否具有标志g。如果regexp没有标志g,那么match()方法就只能在stringObject中执行一次匹配。如果没有找到任何匹配的文本,match()将返回null。否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。该数组的第0 个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本。除了这些常规的数组元素之外,返回的数组还含有两个对象属性。index属性声明的是匹配文本的起始字符在stringObject中的位置,input属性声明的是对stringObject的引用。如果regexp具有标志g,则match()方法将执行全局检索,找到stringObject中的所有匹配子字符串。若没有找到任何匹配的子串,则返回null。如果找到了一个或多个匹配子串,则返回一个数组。不过全局匹配返回的数组的内容与前者大不相同,它的数组元素中存放的是stringObject中所有的匹配子串,而且也没有index属性或input属性。
例子:
var str = "112AAB333CC";
var patt1 = /\d+/;
var result1=str.match(patt1);//返回112
document.write("不加g:"+result1+"<br />");
var patt2 = /\d+/g;
var result2=str.match(patt2);//返回112,333
document.write("加g:"+result2+"<br />");
1.4.3 replace(regexp/substr,replacement)
返回值
一个新的字符串,是用replacement替换了regexp的第一次匹配或所有匹配之后得到的。
说明
字符串stringObject的replace()方法执行的是查找并替换的操作。它将在stringObject中查找与regexp相匹配的子字符串,然后用replacement来替换这些子串。如果regexp具有全局标志g,那么replace()方法将替换所有匹配的子串。否则,它只替换第一个匹配子串。replacement 可以是字符串,也可以是函数。如果它是字符串,那么每个匹配都将由字符串替换。但是replacement中的$ 字符具有特定的含义。
如下表所示,它说明从模式匹配得到的字符串将用于替换。
注意:ECMAScript v3规定,replace()方法的参数replacement可以是函数而不是字符串。在这种情况下,每个匹配都调用该函数,它返回的字符串将作为替换文本使用。该函数的第一个参数是匹配模式的字符串。接下来的参数是与模式中的子表达式匹配的字符串,可以有0 个或多个这样的参数。接下来的参数是一个整数,声明了匹配在stringObject中出现的位置。最后一个参数是stringObject本身。
1.4.3.1 replace(正则,字符串)
例子1:$`和$’的运用
var str = "112AAB333CC";
var patt1 = /[a-z]+/i;
var result1=str.replace(patt1,"$`");
document.write("用位于匹配到的字符串左侧的字符串来替换匹配到的字符串:
"+result1+"<br />");
var patt2 = /\d+/;
var result2=str.replace(patt2,"$'");
document.write(" 用位于匹配到的字符串右侧的字符串来替换匹配到的字符串:
"+result2+"<br />");
结果(思考一下过程):
原字符串:112AAB333CC
用位于匹配到的字符串左侧的字符串来替换匹配到的字符串:112112333CC
用位于匹配到的字符串右侧的字符串来替换匹配到的字符串:AAB333CCAAB333CC
例子2:$$的运用
var str = "112¥,333¥";
document.write("原字符串:"+str+"<br />");
var patt1 = /¥/g;
var result1=str.replace(patt1,"$$");//"$"这样也可以
document.write("用$替换¥后:"+result1+"<br />");
结果:
原字符串:112¥,333¥
用$替换¥后:112$,333$
例子3:$&的运用
var str = "112,333";
document.write("原字符串:"+str+"<br />");
var patt1 = /\d+/g;
var result1=str.replace(patt1,"$&cm");
document.write("在数字后面加单位cm:"+result1+"<br />");
结果:
原字符串:112,333
在数字后面加单位cm:112cm,333cm
例子4:$1、$2...$99 的运用
var str = "112aaa,333bbb";
document.write("原字符串:"+str+"<br />");
var patt1 = /(\d+)([a-z]+)/g;
var result1=str.replace(patt1,"$2$1");
document.write("数字和字母互换位置:"+result1+"<br />");
结果:
原字符串:112aaa,333bbb
数字和字母互换位置:aaa112,bbb333
1.4.3.2 replace(正则,function(){})
1.4.4 split(separator,howmany)
返回值
一个字符串数组。该数组是通过在separator 指定的边界处将字符串stringObject 分割成子串创建的。返回的数组中的字串不包括separator 自身。但是,如果separator 是包含子表达式的正则表达式,那么返回的数组中包括与这些子表达式匹配的字串(但不包括与整个正则表达式匹配的文本)。
注释:如果把空字符串("") 用作separator,那么stringObject 中的每个字符之间都会被分割。
注释:String.split() 执行的操作与Array.join 执行的操作是相反的。
例子1:
var str = "1 2,3#9|8.10";
document.write("原字符串:"+str+"<br />");
var result1=str.split(/[\s,#|.]/);
//str.split("[\\s,#|.]")这样写在js 中是错误的,但java 中可以这样写
document.write("分割字符串:"+result1+"<br />");
结果:
原字符串:1 2,3#9|8.10
分割字符串:1,2,3,9,8,10
例子2:
(function(){
var str='sol1+avg(sole2,sole3,sole4)/sole5';
//没有分组
var arr1=str.split(/[+(),\/]/);
//有捕获组
var arr2=str.split(/([+(),\/])/);
//非捕获组
var arr3=str.split(/(?:[+(),\/])/);
})();
结果:
说明:
可以看出,没有分组和非捕获组分割后的结果是一样的,而又捕获组的结果如下:
也就是说,利用捕获组的时候,那些分隔符也将成为数组结果的一部分,这一点跟java就不太一样了