你的位置:首页 > Java教程

[Java教程]JavaScript:RegExp类型


JavaScript通过RegExp类型来支持正则表达式。语法:

var exepression = /pattern/flags;

其中,pattern可以任意的正则表达式,可以包含字符类限定符分组向前查找以及反向引用。每一个正则表达式都可带一个或多个标志,用于标明正则表达式的行为。

  • g:表示全局模式,即模式将被应用于所有字符串,而非在发现第一个匹配项时立即停止
  • i:表示不区分大小写模式,即在匹配项时忽略模式与字符串的大小写
  • m:表示多行模式,即到达一行文本末尾时还会继续查找下一行是否存在匹配项

举例:

// 匹配字符串中所有“at”的实例var pattern1 = /at/g;// 匹配第一个“bat”或“cat”,不区分大小写var pattern2 = /[bc]at/i;// 匹配所有以“at”结尾的3个字符的组合,不区分大小写var pattern3 = /.at/gi;

上面的例子中用到的“[”、“]”、“.”是元字符(类似于编程语言的保留字,使用的时候需要进行转义)。

// 匹配第一个“[bc]at”,不区分大小写var pattern2 = /\[bc\]at/i;// 匹配所有“.at”,不区分大小写var pattern4 = /\.at/gi;

另一种创建正则表达式的方式是构造函数:

var exepression = new RegExp("pattern", "flags");

构造函数的第一个参数是字符串形式的模式,在默写情况下需要对字符进行双重转义。所有元字符都必须双重转义,已经转义过的字符也是如此,例如,\n(字符\在字符串中通常被转义为\,而在正则表达式字符串中就会变成\\)。

使用正则表达式字面量和使用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实例,由于实例属性不会重置,所以在循环中再次调用test()会失败,因为第二次调用时从索引为3的字符("cat"后面的“a”)开始。

第二个循环使用RegExp构造函数,在每次循环中都会创建正则表达式。因此每次迭代都会创建一个新的RegExp实例,所以每次调用test()都会返回true。

实例属性

RegExp的每个实例都具有下列属性,通过这些属性可以获取模式的各种信息。

  • global:布尔值,表示是否设置了g标志。
  • ignoreCase:布尔值,表示是否设置了i标志
  • lastIndex:整数,表示开始搜索下一个匹配项的字符起始位置,从0开始
  • multiline:布尔值,表示是否设置了m标志
  • source:正则表达式的字符串表示,按照字面量形式而非传入构造函数中的字符串模式返回

    var pattern = /[bc]at/i; alert(pattern.global); // false alert(pattern.ignoreCase); // true alert(pattern.multiline); // false alert(pattern.lastIndex); // 0 alert(pattern.source); // "/[bc]at"

实例方法

exec()方法

exec()接收一个参数,即要应用模式的的字符串,返回包含第一个匹配项信息的数组,如果没有匹配项就返回null。返回的数组虽然是Array的实例,但是包含两个额外的属性:

  • index:表示匹配项在字符串中的位置
  • input:表示应用正则表达式的字符串

在数组中,第一项是与整合模式匹配的字符串,其他项是与模式中的捕获组匹配的字符串(如果模式中没有捕获组,则该数组值包含一项。)

var text = "mom and dad and baby";var pattern = /mom( and dad( and baby)?)?/gi;var matchers = pattern.exec(text);alert(matchers.index);alert(matchers.index); // "mom and dad and baby"alert(matchers[0]);   // "mom and dad and baby"alert(matchers[1]);   // " and dad and baby"alert(matchers[2]);   // " and baby"

对于exec()方法而言,即使在模式中设置了全局标志,它每次也只会返回一个匹配项。在不设置全局标志的情况下,在同一个字符串上多次调用exec()将始终匹配第一个匹配项的信息。而在设置全局标志的情况下,每次调用exec()都会在字符串中继续查找新匹配项:

var text = "cat, bat, sat, fat";var pattern1 = /.at/;var matches = pattern1.exec(text);alert(matches.index);  // 0alert(matches[0]);   // catalert(pattern1.lastIndex); // 0matches = pattern1.exec(text);alert(matches.index);  // 0alert(matches[0]);   // catalert(pattern1.lastIndex);  // 0var pattern2 = /.at/g;var matches = pattern2.exec(text);alert(matches.index);  // 0alert(matches[0]);   // catalert(pattern2.lastIndex); // 3matches = pattern2.exec(text);alert(matches.index);  // 5alert(matches[0]);   // batalert(pattern2.lastIndex); // 8

在第一个非全局模式下,每次返回第一个匹配项;而在第二个全局模式下,每次返回字符串中的下一个匹配项。在全局模式下,lastIndex的值在每次调用exec()后都会增加,而在全局模式下则不会变。

test()方法

test()方法接收一个字符串参数。在模式与参数匹配的情况下返回true;否则,返回false。

var text = "000-00-000";var pattern = /\d{3}-\d{2}-\d{3}/;if (pattern.test(text)) {  alert("匹配成功");}

RegExp实例继承的toLocaleString()和toString()方法都会返回正则表达式的字面量,与创建正则表达式的方式无关。

var pattern = new RegExp("\\[bc\\]at", "gi");alert(pattern.toString());     // /\[bc\]at/gialert(pattern.toLocaleString());  // /\[bc\]at/gi

RegExp构造函数属性

RegExp构造函数包含一些属性(Opera不支持),这些属性可以作用于作用域中的所有正则表达式,这些属性分别有长属性名和短属性名两种访问方式。

长属性名短属性名说明
input$_最近一次要匹配的字符串
lastMatch$&最近一次的匹配项
lastParent$+最近一次的捕获组
rightContext$*最近一次的捕获组
rightContext$'Input字符串中lastMatch之后的文本

使用这些属性可以从exec()或test()执行的操作中提取更具体的信息。下面通过长属性名访问:

var text = "what are you doing now";var pattern = /(.)ng/g;if (pattern.test(text)) {  alert(RegExp.input);    // what are you doing now  alert(RegExp.leftContext); // what are you do  alert(RegExp.rightContext); // now  alert(RegExp.lastMatch);  // ing  alert(RegExp.lastParen);  // i  alert(pattern.multiline);  // false}

下面通过短属性名访问:

var text = "what are you doing now";var pattern = /(.)ng/g;if (pattern.test(text)) {  alert(RegExp.$_);    // what are you doing now  alert(RegExp["$`"]); // what are you do  alert(RegExp["$'"]); // now  alert(RegExp["$&"]);  // ing  alert(RegExp["$+"]);  // i}

除了上面的属性外,还有9个用于存储捕获组的构造函数属性:RegExp.$1...RegExp.$9,分别存储第一...第九个匹配的捕获组。

var text = "what are you doing now";var pattern = /(..)in(.)/g;if (pattern.test(text)) {  alert(RegExp.$1);  // do  alert(RegExp.$2);  // g}

模式的局限性

JavaScript正则表达式不支持的特性:

  • 匹配字符串开始和结尾的\A和\Z锚
  • 向后查找
  • 并集和交集类
  • 原子组
  • Unicode支持
  • 命名的捕获组
  • s(single,单行)和x(free-spacing,无间隔)匹配模式
  • 条件匹配
  • 正则表达式注释