正则表达式字面量
JavaScript中的正则表达式也是对象,可以通过两种方式创建它们:
- 使用
new RegExp()
构造函数 - 使用正则表达式字面量
下面的示例代码展示了创建用来匹配一个反斜杠(\)的正则表达式的两种方法:
// 正则表达式字面量
var re = /\\/gm;
// 构造函数
var re = new RegExp("\\\\", "gm");
显然正则表达式字面量写法的代码更短,而且不会让你觉得在用像类一样的构造函数的思想在写正则表达式,因此更推荐使用字面量写法。
另外,如果使用RegExp()
构造函数写法,还需要考虑对引号和反斜杠进行转义,正如上段代码所示的那样,用了四个反斜杠来匹配一个反斜杠。这会增加正则表达式的长度,而且让它变得难于理解和维护。正则表达式入门不是件容易的事,所以不要放弃任何一个简化它们的机会,尽量使用字面量而不是通过构造函数来创建正则表达式。
正则表达式字面量语法
正则表达式字面量使用两个斜杠包裹,主体部分不包括两端的斜线。在第二个斜线之后可以指定模式匹配的修饰符,修饰符不需要用引号引起来,JavaScript中有三个修饰符:
g
,全局匹配m
,多行匹配i
,忽略大小写的匹配
修饰符可以自由组合,而且与顺序无关:
var re = /pattern/gmi;
使用正则表达式字面量可以让代码更加简洁高效,比如当调用String.prototype.replace()
方法时,可以传入正则表达式参数:
var no_letters = "abc123XYZ".replace(/[a-z]/gi, "");
console.log(no_letters); // 123
有一种不得不使用new RegExp()
的场景,就是正则表达式是不确定,只有等到运行时才能确定下来的情况。
正则表达式字面量和构造函数还有另一个区别,就是字面量只在解析时创建一次正则表达式对象(译注:多次解析同一个正则表达式,会产生相同的实例对象)。如果在循环体内反复使用相同的字面量创建对象,则会返回第一次创建的对象以及它的属性(比如lastIndex
)。下面这个例子展示了两次返回相同的正则表达式的情形。
function getRE() {
var re = /[a-z]/;
re.foo = "bar";
return re;
}
var reg = getRE(),
re2 = getRE();
console.log(reg === re2); // true
reg.foo = "baz";
console.log(re2.foo); // "baz"
在ECMAScript5中这种情况有所改变,相同正则表达式字面量的每次计算都会创建新的实例对象,目前很多现代浏览器也对此做了纠正。
最后需要提一点,不带new
调用RegExp()
(作为普通的函数)和带new
调用RegExp()
是完全一样的。