RegExp类型
定义方法一:字面量形式
var expression = / pattern / flags ;
其中的模式(pattern)部分可以是任何简单或复杂的正则表达式,可以包含字符类、限定符、分组、 向前查找以及反向引用。每个正则表达式都可带有一或多个标志(flags),用以标明正则表达式的行为。 正则表达式的匹配模式支持下列 3 个标志:
- g: 表示全局(global)模式,即模式将被应用于所有字符串,而非在发现第一个匹配项时立即停止;
- i: 表示不区分大小写(case-insensitive)模式,即在确定匹配项时忽略模式与字符串的大小写;
- m: 表示多行(multiline)模式,即在到达一行文本末尾时还会继续查找下一行中是否存在与模式匹配的项。
一个正则表达式就是一个模式与上述 3 个标志的组合体。模式中使用的所有元字符都必须转义。
记录点 1 正则表达式中的元字符包括: ( [ { \ ^ $ | ) ? * + .]}
/** 匹配第一个"bat"或"cat",不区分大小写 */
var pattern1 = /[bc]at/i;
/** 匹配第一个" [bc]at",不区分大小写 */
var pattern2 = /\[bc\]at/i;
/** 匹配所有以"at"结尾的 3 个字符的组合,不区分大小写 */
var pattern3 = /.at/gi;
/** 匹配所有".at",不区分大小写 */
var pattern4 = /\.at/gi;
定义方法二:RegExp 构造函数
可以 使用字面量定义的任何表达式,都可以使用构造函数来定义,如下面的例子所示:
/** 匹配第一个"bat"或"cat",不区分大小写 */
var pattern1 = /[bc]at/i;
/** 与 pattern1 相同,只不过是使用构造函数创建的 */
var pattern2 = new RegExp("[bc]at", "i");
要注意的是,传递给 RegExp 构造 函数的两个参数都是字符串(不能把正则表达式字面量传递给 RegExp 构造函数)。
记录点 2 RegExp 构造 函数的模式参数是字符串,所有元字符都必须双重转义。
例如\n(字符\在字符串中通常被转义为\,而在正则表达式字符串中就 会变成\\)。
下表给出了一些模式,左边是这些模式的字面量形式,右边是使用 RegExp 构造函数定义 相同模式时使用的字符串:
字面量模式 | 等价的字符串 |
---|---|
/[bc]at/ | “[bc]at”(待确定) |
/.at/ | “\.at” |
/name/age/ | “name\/age” |
/\d.\d{1,2}/ | “\d.\d{1,2}” |
/\w\hello\123/ | “\w\\hello\\123” |
在 ECMAScript 3 中, 正则表达式字面量始终会共享同一个RegExp实例,而使用构造函数创建的每一个新RegExp实例都是一个新实例。来看下面的例子。
var re = null, i;
for (i=0; i < 10; i++){
re = /cat/g;
re.test("catastrophe");
}
for (i=0; i < 10; i++){
re = new RegExp("cat", "g");
re.test("catastrophe");
}
说明:在第一个循环中,即使是循环体中指定的,但实际上只为/cat/创建了一个 RegExp 实例。由于实 4 例属性不会重置,所以在循环中再次调用 test()方法会失败。这是因为第一 次调用 test()找到了"cat",但第二次调用是从索引为 3 的字符(上一次匹配的末尾)开始的,所以 就找不到它了。由于会测试到字符串末尾,所以下一次再调用 test()就又从开头开始了。
第二个循环使用 RegExp 构造函数在每次循环中创建正则表达式。因为每次迭代都会创建一个新的 RegExp 实例,所以每次调用 test()都会返回 true。
ECMAScript 5 明确规定,使用正则表达式字面量必须像直接调用 RegExp 构造函数一样,每次都创 建新的 RegExp 实例。
RegExp实例属性
RegExp 的每个实例都具有下列属性,通过这些属性可以取得有关模式的各种信息。
- global: 布尔值,表示是否设置了 g 标志;
- ignoreCase: 布尔值,表示是否设置了 i 标志;
- lastIndex: 整数,表示开始搜索下一个匹配项的字符位置,从 0 算起;
- multiline: 布尔值,表示是否设置了 m 标志;
- source: 正则表达式的字符串表示,按照字面量形式而非传入构造函数中的字符串模式返回。
RegExp实例方法
exec()
RegExp 对象的主要方法是 exec(),该方法是专门为捕获组而设计的。exec()接受一个参数,即 要应用模式的字符串,然后返回包含第一个匹配项信息的数组;或者在没有匹配项的情况下返回 null。
返回的数组虽然是 Array 的实例,但包含两个额外的属性:index 和 input。其中,index 表示匹配项在字符串中的位置,而 input 表示应用正则表达式的字符串。在数组中,第一项是与整个模式匹配的字符串,其他项是与模式中的捕获组匹配的字符串(如果模式中没有捕获组,则该数组只包含一项)。 请看下面的例子。
var text = "mom and dad and baby";
var pattern = /mom( and dad( and baby)?)?/gi;
var matches = pattern.exec(text);
alert(matches.index); // 0
alert(matches.input); // "mom and dad and baby"
alert(matches[0]); // "mom and dad and baby"
alert(matches[1]); // " and dad and baby"
alert(matches[2]); // " and baby"
对于 exec()方法而言,即使在模式中设置了全局标志(g),它每次也只会返回一个匹配项。在不 设置全局标志的情况下,在同一个字符串上多次调用 exec()将始终返回第一个匹配项的信息。而在设 置全局标志的情况下,每次调用 exec()则都会在字符串中继续查找新匹配项,如下面的例子所示:
var text = "cat, bat, sat, fat";
var pattern1 = /.at/;
var matches = pattern1.exec(text);
alert(matches.index); //0
alert(matches[0]); //cat
alert(pattern1.lastIndex); //0
matches = pattern1.exec(text);
alert(matches.index); //0
alert(matches[0]); //cat
alert(pattern1.lastIndex); //0
var pattern2 = /.at/g;
var matches = pattern2.exec(text);
alert(matches.index); //0
alert(matches[0]); //cat
alert(pattern2.lastIndex); //3
matches = pattern2.exec(text);
alert(matches.index); //5
alert(matches[0]); //bat
alert(pattern2.lastIndex); //8
test()
正则表达式的第二个方法是 test(),它接受一个字符串参数。在模式与该参数匹配的情况下返回 true;否则,返回 false。
RegExp构造函数属性
RegExp 构造函数包含一些属性(这些属性在其他语言中被看成是静态属性)。这些属性适用于作用域中的所有正则表达式,并且基于所执行的最近一次正则表达式操作而变化。关于这些属性的另一个独特之处,就是可以通过两种方式访问它们。换句话说,这些属性分别有一个长属性名和一个短属性名 (Opera 是例外,它不支持短属性名)。下表列出了 RegExp 构造函数的属性:
长属性名 | 短属性名 | 说明 |
---|---|---|
input | $_ | 最近一次要匹配的字符串。Opera未实现此属性 |
lastMatch | $& | 最近一次的匹配项。Opera未实现此属性 |
lastParen | $+ | 最近一次匹配的捕获组。Opera未实现此属性 |
leftContext | $` | input字符串中lastMatch之前的文本 |
multiline | $* | 布尔值,表示是否所有表达式都使用多行模式。IE和Opera未实现此属性 |
rightContext | $’ | Input字符串中lastMatch之后的文本 |
使用这些属性可以从 exec()或 test()执行的操作中提取出更具体的信息。请看下面的例子。
var text = "this has been a short summer";
var pattern = /(.)hort/g;
/*
* 注意:Opera 不支持 input、lastMatch、lastParen 和 multiline 属性
* Internet Explorer 不支持 multiline 属性
*/
if (pattern.test(text)){
alert(RegExp.input); // this has been a short summer
alert(RegExp.leftContext); // this has been a
alert(RegExp.rightContext);// summer
alert(RegExp.lastMatch); // short
alert(RegExp.lastParen); // s
alert(RegExp.multiline); // false
}
input 属性返回了原始字符串;
leftContext 属性返回了单词 short 之前的字符串,而 rightContext 属性则返回了 short 之后的字符串;
lastMatch 属性返回最近一次与整个正则表达式匹配的字符串,即 short;
lastParen 属性返回最近一次匹配的捕获组,即例子中的 s。
除了上面介绍的几个属性之外,还有多达 9 个用于存储捕获组的构造函数属性。访问这些属性的语 法是 RegExp.$1、RegExp.$2…RegExp.$9,分别用于存储第一、第二…第九个匹配的捕获组。在 调用 exec()或 test()方法时,这些属性会被自动填充。
var text = "this has been a short summer";
var pattern = /(..)or(.)/g;
if (pattern.test(text)){
alert(RegExp.$1); //sh
alert(RegExp.$2); //t
}
这里创建了一个包含两个捕获组的模式,并用该模式测试了一个字符串。即使 test()方法只返回 一个布尔值,但 RegExp 构造函数的属性$1 和$2 也会被匹配相应捕获组的字符串自动填充。
附:一些开发中实例
// 可以匹配 "main.js", "/main.js", "?main.js"
jsExtRegExp = /^\/|:|\?|\.js$/;
至此,结束。