RegExp对象应用

JavaScript 中的 RegExp 对象表示正则表达式,它是对字符串执行模式匹配的强大工具。

前面章节介绍过,可以通过直接量语法或 RegExp 对象构造方法创建正则表达式对象,如下:

直接量语法

/pattern/attributes

例如:

var myPattern = /^[a-zA-Z]{4,8}$/g;

其中,“^[a-zA-Z]{4,8}$” 为 pattern,g 为 attributes。

构造函数

new RegExp(pattern, attributes)

参数说明

  • pattern 一个字符串,指定了正则表达式的模式或其他正则表达式。

  • attributes 一个可选的字符串,包含属性 “g”、“i” 和 “m”,分别用于指定全局匹配、区分大小写的匹配和多行匹配。ECMAScript 标准化之前,不支持 m 属性。如果 pattern 是正则表达式,而不是字符串,则必须省略该参数。

返回值

上面语句将返回一个新的 RegExp 对象,具有指定的正则表达式和标志。

如果参数 pattern 是正则表达式而不是字符串,那么 RegExp() 构造函数将用与指定的 RegExp 相同的模式和标志创建一个新的 RegExp 对象。

如果不用 new 运算符,将 RegExp() 作为函数调用,那么它的行为与用new 运算符调用时一样,只是当 pactern 是正则表达式时,它只返回 pattern,而不再创建一个新的 RegExp 对象。

抛出

SyntaxError

如果pattern不是合法的正则表达式,或attributes含有“g”、“i”、“m”之 外的字符,抛出该异常。

TypeError

如果pattern是RegExp对象,但没有省略attributes参数,抛出该异常。

实例属性

global 

RegExp 对象的属性 global 是一个只读的布尔值。它声明了给定的正则表达式是否执行全局匹配,例如创建它时是否使用了性质 g。实例:

var myPattern = new RegExp("^[A-Z][a-zA-Z0-9_]{1,}[a-zA-Z]$", "g");
var myCode = "A001B";
if(myCode.match(myPattern)) {
  alert("OK " + (myPattern.global ? "启用全局匹配" : "")); 
} else {
  alert("Fail");
}

上面实例中,myPattern.global 将返回 true,因为我们使用 RegExp 创建正则表达式对象时指定了性质 g。

ignoreCase 

RegExp 对象的属性 ignoreCase 是一个只读的布尔值。它声明了一个给定的正则表达式是否执行区分大小写的匹配,例如创建它时是否使用了性质 i。实例:

var myPattern = new RegExp("^[a-z][a-z0-9_]{1,}[a-z]$", "i");
var myCode = "A001B";
if(myCode.match(myPattern)) {
  alert("OK " + (myPattern.ignoreCase ? "启用忽略大小写" : "")); 
} else {
  alert("Fail");
}

上面实例中,myPattern.ignoreCase 将返回 true,因为我们使用 RegExp 创建正则表达式对象时指定了性质 i。

multiline 

RegExp 对象的属性 multiline 是一个只读的布尔值。它声明了一个给定的正则表达式是否为多行模式匹配,例如创建它时是否具有 m 性质。实例:

var myPattern = new RegExp("^[a-zA-Z][a-zA-Z0-9_]{1,}[a-zA-Z]$", "m");
var myCode = "A001B\r\nA002B\r\nA003C";
if(myCode.match(myPattern)) {
  alert("OK " + (myPattern.multiline ? "启用多行" : "")); 
} else {
  alert("Fail");
}

source 

RegExp 对象的属性 source 将返回正则表达式的源文本。实例:

var myPattern = new RegExp("^[a-zA-Z][a-zA-Z0-9_]{1,}[a-zA-Z]$", "m");
alert(myPattern.source);

上面实例,仅仅返回正则表达式原文 “^[a-zA-Z][a-zA-Z0-9_]{1,}[a-zA-Z]$”,并不会返回性质 m。

lastIndex 

RegExp 对象的属性 lastIndex 是一个可读可写的值。对于设置了 g 性质的正则表达式来说,该属性存放的是—个整数,它声明了紧接着上次找到的匹配文本的字符的位置。上次匹配的结果是由方法 RegExp.exec() 或 RegExp.test() 找到的,它们都以 lastIndex 属性所指的位置作为下次检索的起始点。这样,就可以通过反复调用这两个方法来遍历一个字符串中的所有匹配文本。实例:

var myPattern = new RegExp("[a-zA-Z]+", "g");
var myCode = "AAA_BBB_CCC";
myPattern.exec(myCode);
console.log(myPattern.lastIndex); // 3

myPattern.exec(myCode);
console.log(myPattern.lastIndex); // 7

myPattern.exec(myCode);
console.log(myPattern.lastIndex); // 11

上面实例调用了三次 RegExp 的 exec() 方法,每次调用 exec() 方法后输出的 lastIndex 均不一样,且这些 lastIndex 是紧接着上次找到的匹配文本的字符的位置。

由于这一属性是可读可写的,所以只要目标字符串的下一次搜索开始,就可以对它进行设置。当方法 exec() 或 test() 再也找不到可以匹配的文本时,它们会自动地把 lastIndex 属性重置为 0。

实例:通过 for 语句来执行 exec() 方法,如下:

var myPattern = new RegExp("[a-zA-Z]+", "g");
var myCode = "AAA_BBB_CCC";
for(;myPattern.exec(myCode);myPattern.lastIndex > 0){
	console.log(myPattern.lastIndex);      
}

运行上面实例将输出:

3
7
11

如果在成功的匹配了某个字符串之后就开始检索另一个字符串,需要明确地把这个属性设为 0。实例:

var myPattern = new RegExp("[a-zA-Z]+", "g");
var myCode1 = "AAA_BBB_000";
var myCode2 = "AAA_BBB_000";
myPattern.exec(myCode1);
console.log(myPattern.lastIndex); // 3

myPattern.exec(myCode1);
console.log(myPattern.lastIndex); // 7

// 这是因为此时的 lastIndex 为 7
// 此时匹配“AAA_BBB_000”将从 B_ 位置开始匹配,匹配失败
myPattern.exec(myCode2);
console.log(myPattern.lastIndex); // 0

myPattern.lastIndex = 4;
myPattern.exec(myCode2);
console.log(myPattern.lastIndex); // 7

注意:不具有性质 g 和不表示全局模式的 RegExp 对象不能使用 lastlndex 属性。

方法

exec(string) 

在所有的 RegExp 模式匹配方法和 String 模式匹配方法中,exec() 的功能最强大。它是一个通用的方法,使用起来比 RegExp.test()、String.search()、String.replace() 和 String.match() 都复杂。

exec() 将检索字符串 string,从中得到与正则表达式 regexp 相匹配的文本。如果 exec() 找到了匹配的文本,它就会返回一个结果数组。否则,返回 null。这个返回数组的第 0 个元素就是与表达式相匹配的文本。第 1 个元素是与regexp的第一个子表达式相匹配的文本(如果存在)。第2个元素是与regexp的第二个子表达式相匹配的文本,以此类推。通常,数组的 length 属性声明的是数组中的元素个数。除了数组元素和 length 属性之外,exec() 还返回两个属性。index 属性声明的是匹配文本的第一个字符的位置。input 属性指的就是 string。在调用非全局RegExp 对象的 exec() 方法时,返回的数组与调用方法 String.match() 返回的方法相同。 

在调用非全局模式的 exec() 方法时,它将进行检索,并返回上述结果。不过,当 regexp 是一个全局正则表达式时,exec() 的行为就稍微复杂一些。它在 regexp 的属性 lastlndex 指定的字符处开始检索字符串 string。当它找到了与表达式相匹配的文本时,在匹配之后,它将把regexp 的 lastlndex 属性设置为匹配文本的第一个字符的位置。这就是说,可以通过反复地调用 exec() 方法来遍历字符串中的所有匹配文本。当 exec() 再也找不到匹配的文本时,它将返回 null,并且把属性 lastlndex 重置为 0。如果在另一个字符串中完成了一次模式匹配之后要开始检索新的字符串,就必须手动地把 lastlndex 属性重置为 0。

注意,无论 regexp 是否是全局模式,exec() 都会将完整的细节添加到它返回的数组中。这就是 exec() 和 String.match() 的不同之处,后者在全局模式下返回的信息要少得多。事实上,在循环中反复地调用 exec() 方法是惟一种获得全局模式的完整模式匹配信息的方法。

示例

可以在循环中使用exec()来检索—个字符串中的所有匹配文本。例如:

var pattern = /\bJava\w*\b/g;
var text = "JavaScript is more fun than Java or JavaBeans!";
var result;
while((result = pattern.exec(text)) != null) {
  console.log("匹配到 `" + result[0] + "' 位置 " + result.index +
        " 下次检索匹配开始位置 " + pattern.lastIndex);
}

运行程序结果如下:

匹配到 `JavaScript' 位置 0 下次检索匹配开始位置 10
匹配到 `Java' 位置 28 下次检索匹配开始位置 32
匹配到 `JavaBeans' 位置 36 下次检索匹配开始位置 45

test(string) 

方法 test() 将检测字符串 string,看它是否含有与 regexp 相匹配的文本。如果 string 中含有这样的文本,该方法将返回 true,否则,返回 false。调用 RegExp 对象的 test() 方法,给它传递字符串 string,等价于下面的表达式:

(regexp.exec(string) != null)

示例:

var pattern = /java/i;
pattern.test("JavaScript");   // 返回 true
pattern.test("ECMAScript");   // 返回 false
说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号