预备知识
replace()方法大家一定很熟悉了吧,
stringObject.replace(regexp/substr,replacement)
w3school里面有一段话相信大家也看过了:
注意:ECMAScript v3 规定,replace() 方法的参数 replacement可以是函数而不是字符串。在这种情况下,每个匹配都调用该函数,它返回的字符串将作为替换文本使用。该函数的第一个参数是匹配模式的字符串。接下来的参数是与模式中的子表达式匹配的字符串,可以有0 个或多个这样的参数。接下来的参数是一个整数,声明了匹配在 stringObject 中出现的位置。最后一个参数是stringObject 本身。
不知道大家有没有注意过这个子表达式是啥意思,很简单,括号里面的就是子表达式。好了,知道这个我们就可以开始后向引用的学习了。
后向引用
- 作用:后向引用用于重复搜索前面某个分组匹配的文本。
- 说明:使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。
是不是感觉云里雾里的?下面看代码,一目了然。
例1、检查重复字符串
给定字符串 str,检查其是否包含连续重复的字母(a-zA-Z),包含返回 true,否则返回 false。
肯定有人会遍历一遍字符串,判断str.charAt(i)与str.charAt(i+1)是否相同来做吧。看看下面的代码:
function containsRepeatingLetter(str) {
return /([a-zA-Z])\1/.test(str);
}
只要一行,简洁吧。这行代码啥意思呢?首先匹配到大写或者小写字母,因为有括号,将它作为分组1,\1代表分组1匹配的文本。匹配了括号里面的字母一次,又通过\1再次匹配分组1即这个括号里面的字母一次,不就是匹配了两次该字母,不就可以判断是否有重复的字母了吗?
例2、检查指定类型字符串
给定字符串 str,检查其是否包含按照数字、小写字母、大写字母、小写字母排列的字符串,包含返回 true,否则返回 false。
代码如下:
function judgeString(str) {
return /(\d)([a-z])([A-Z])\2/.test(str)
}
judgeString("1aAa"); //true
judgeString("1aAb"); //false
judgeString("1aA1"); //false
当然,你也可以弄复杂一点,/(\d)([a-z])([A-Z])\2\1/
这样的规则。
最后
是不是感觉已经明白了后向引用呢?别急,前面只是最基本的使用哦,还是很多东西没有说呢。
(?:exp)
:不捕获匹配的文本,也不给此分组分配组号。
function judgeString(str) {
if(/(\d)(?:[a-z])([A-Z])\2/.test(str)) {
console.log(RegExp.$1);
console.log(RegExp.$2);
return true;
} else {
return false;
}
}
judgeString("1aAa"); //false
judgeString("1aAA"); //true,1,A
分组嵌套
function judgeString(str) {
if(/(\d)([a-z](\d))([A-Z])/.test(str)) {
console.log("RegExp.$1:"+RegExp.$1);
console.log("RegExp.$2:"+RegExp.$2);
console.log("RegExp.$3:"+RegExp.$3);
console.log("RegExp.$4:"+RegExp.$4);
return true;
} else {
return false;
}}
judgeString("1a3Aa"); //RegExp.$1:1
//RegExp.$2:a3
//RegExp.$3:3
//RegExp.$4:A
//true
水平有限,很多内容没有列举。除此此外,还有零宽断言,下次再说。