首页 » 编写高质量代码:改善JavaScript程序的188个建议 » 编写高质量代码:改善JavaScript程序的188个建议全文在线阅读

《编写高质量代码:改善JavaScript程序的188个建议》建议41:正确使用正则表达式引用

关灯直达底部

正则表达式在执行匹配运算时会自动把每个分组(子表达式)匹配的文本都存储在一个特殊的地方以备将来使用。这些存储在分组中的特殊值被称为反向引用。反向引用将遵循从左到右的顺序,根据表达式中左括号字符的顺序进行创建和编号。


var s="abcdefghijklmn";

var r=/(a(b(c)))/;

var a=s.match(r);//["abc","abc","bc","c"]


在这个分组匹配模式中,共产生了3个反向引用,第一个是“(a(b(c)))”,第二个是“(b(c))”,第三个是“(c)”。它们引用的匹配文本分别是字符串“abc”、“bc”和“c”。

反向引用在应用开发中主要有以下几种常规用法。

1)在正则表达式对象的test方法,以及字符串对象的match和search等方法中使用。在这些方法中,反向引用的值可以从RegExp构造函数中获得。例如:


var s="abcdefghijklmn";

var r=/(/w)(/w)(/w)/;

r.test(s);

alert(RegExp.$1);//第1个子表达式匹配的字符a

alert(RegExp.$2);//第2个子表达式匹配的字符b

alert(RegExp.$3);//第3个子表达式匹配的字符c


在正则表达式执行匹配测试后,所有子表达式匹配的文本都被分组存储在RegExp构造函数的属性内,通过前缀符号$与正则表达式中子表达式的编号来引用这些临时属性,其中属性$1标识符指向第一个值引用,属性$2标识符指向第二个值引用,依此类推。

2)可以直接在定义分组的表达式中包含反向引用。这可以通过使用特殊转义序列(如/l、/2等)来实现。例如:


var s="abcbcacba";

var r=/(/w)(/w)(/w)/2/3/1/3/2/1/;

var b=r.test(s);//验证正则表达式是否匹配该字符串

alert(b);//true


在上面的正则表达式中,“/1”表示对第一个反向引用(/w)所匹配的字符a的引用,“/2”表示对第二个反向引用(/w)所匹配的字符b的引用,“/3”表示对第二个反向引用(/w)所匹配的字符c的引用。

3)可以在字符串对象的replace方法中使用。通过使用特殊字符序列$1、$2、$3等来实现。例如,在下面的示例中将颠倒相邻字母和数字的位置。


var s="aa11bb22c3d4e5f6";

var r=/(/w+?)(/d+)/g;

var b=s.replace(r,"$2$1");

alert(b);//"11aa22bb3c 4d5e6f"


在这个示例中,正则表达式包括两个分组,第一个分组匹配任意连续的字母,第二个分组匹配任意连续的数字。在replace方法的第二个参数中,$1表示对正则表达式中第一个子表达式匹配文本的引用,而$2表示对正则表达式中第二个子表达式匹配文本的引用,通过颠倒$1和$2标识符的位置即可实现字符串的颠倒以替换原字符串。