14.4 正则表达式的操作方法
理解了正则表达式的构建以及RegExp对象的属性,相信读者都迫切希望知道正则表达式的操作方法。在前面小节中曾提到过正则表达式有七种标准的操作方法,而且在源程序14.1和源程序14.2中分别使用了test() 和exec()方法。下面将详细介绍这几种操作方法。
RegExp对象中的test()方法
RegExp对象中的exec()方法
RegExp对象中的compile()方法
String对象中的search()方法
String对象中的match()方法
String对象中的replace()方法
String对象中的split()方法
14.4.1
test()方法
test()方法是对指定的字符串执行一次测试性搜索,返回一个 Boolean值指示是否存在匹配。
其语法如下所示:
var flag=Object.test(string str);
其中:
Object为RegExp对象实例名称,即创建的正则表达式;
参数str为String对象,是要被查询的字符串,和上面介绍的RegExp对象input属性是一致的,即查找的源;
变量flag为test()方法的返回结果,是一个Boolean类型。若匹配成功,即在被查询字符串中发现正则表达式子字符串,则返回true,否则返回false。
如果test()方法返回true,说明已经匹配成功,并改变RegExp对象中相关静态属性值,如lastIndex属性,把其设置为查找到的第一个匹配字符后的位置。当程序再次执行test()方法时,则直接从lasgIndexz的位置开始查询。特别指出的是test()方法不改变index属性值,从而不能返回匹配结果的确切位置,但可以通过exec()方法实现该功能。
14.4.2
exec()方法
exec()方法是利用创建的RegExp对象实例对指定的字符串执行正则表达式搜索,并返回一个包含结果的数组。
其语法如下所示:
var array=Object.exec(string str);
其中:
Object和参数str的意义和test()方法中的相同,详情请参考test()方法;
变量array为保存搜索结果的数组。当搜索中成功找到正则表达式匹配时,数组元素array[0]包含了完整的匹配结果,而元素array[1]~array[n]依次是表达式模式中定义的各个子匹配的结果。当搜索中没有找到正则表达式的匹配时,exec()方法将返回null。
与test()方法一样,当匹配成功后,exec()方法也会改变相应的静态属性值,如index属性和lastIndex属性分别被设置为第一个匹配的起始位置和终止位置,因此可通过这两个属性找到匹配结果的确切位置。当连续使用exec()方法时,若设置了global属性,则每次搜索从上次exec方法返回的lastIndex开始,否则继续从字符串0位置开始搜索。
值得注意的是,返回的结果数组array也有三个属性:input 、index 和lastIndex。这三个属性可以由array引用,且与使用RegExp引用的效果相同,读者可以参考源程序14.2的运行结果。
14.4.3
compile()方法
compile()方法是更换RegExp对象实例所使用的表达式模式,其语法如下所示:
RegExp.compile("pattern" ,[ "flags"]);
显式定义正则表达式的语法如下所示:
var regularexpression = new RegExp("pattern",["flags"]);
这两个语法结构中的参数是不是一样的?答案是“完全相同”!可见compile()方法只是用显式定义的方式重新定义了一个RegExp对象的实例,并更新到原来的RegExp对象实例当中。
如果compile()方法和显式定义效果一样,那为什么需要compile()方法呢?相比显式定义而言,compile()方法有其优点:compile()方法会将新的表达式模式编译为内部格式,在连续调用时,程序执行更快,该特点对循环结构来说非常有效。但是如果不是连续调用,并且中间又有其他表达式模式执行,则compile()方法没有任何效果。
14.4.4
RegExp对象中三种方法综合举例
上面讲述了RegExp对象对正则表达式的三种操作方法:test()、exec()和compile(),下面通过一个具体实例来加深对上述方法的理解和认识。
考察源程序14.3。
//源程序14.3
<!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.0//EN"
"http://www.w3.org/TR/REC-html140/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Sample Page!</title>
<script language="JavaScript" type="text/javascript">
<!--
function testRegexMethod()
{
//目标字符串
var myString="介绍RegExp对象有关正则表达式的操作方法--第14章 正则表达式";
//隐式构造法创建正则表达式对象
var regex = /RegExp对象/;
//用test方法检测是否含有" RegExp对象"
var flag=regex.test(myString);
//判断boolean值
if(flag)
{
var str="\n目标字符串 : \n";
str+=myString+"\n\n";
str+="查找结果 :\n"
str+="目标字符串中找到''RegExp对象'',程序继续!\n";
//使用compile()方法设置新的表达式
regex.compile("(正则表达式)","g");
//使用exec()方法查找
var array=regex.exec(myString);
if (array)
{
str=str+"第一次exec()方法找到''正则表达式''"
+"\n匹配子串的开始位置index :"+array.index
+"\n匹配子串后面第一个字符的位置lastIndex :"+array.lastIndex
+"\n第一个子匹配的值$1 :" +RegExp.$1;
}
else
{
str=str+"目标字符串中找不到子串''正则表达式'',程序结束!";
alert(str);
}
str+="\n";
//exec()方法第二次查找,查看属性的改变
array=regex.exec(myString);
if(array)
{
str=str+"第二次exec()方法找到''正则表达式''"
+"\n匹配子串的开始位置index :"+array.index
+"\n匹配子串后面第一个字符的位置lastIndex :"+array.lastIndex
+"\n第一个子匹配的值$1 :" +RegExp.$1;
alert(str);
}
else
alert(str);
}
else
{
alert("目标字符串中找不到子串''RegExp对象'',程序结束!");
}
}
-->
</script>
</head>
<body>
<br>
<center>
<p>
RegExp对象三种方法综合实例程序:
</p>
<form onSubmit="return testRegexMethod();">
<input type="submit" value="确定">
</form>
</center>
</body>
</html>
程序运行后,单击原始页面中的“确定”按钮,弹出警告框如图14.6所示。

图14.6 综合实例运行结果
该实例先用test()方法查找,接着用compile()方法定义新的表达式,最后用exec()方法搜索,综合了三种方法,很好地体现了各种方法的应用特色。特别是exec()方法,可以看到连续两次使用时index和lastIndex属性值的变化。程序中compile()方法设置了global属性,读者也可以不设置该属性,看看两次得到的index和lastIndex是否相同,因为exec()方法连续使用时如果不设置global属性,每次都从字符串起始位置重新查找。
14.4.5
search()方法
search()方法是用来搜索字符串中与正则表达式匹配的子字符串的位置。
其语法如下所示:
var index= stringObj.search(regex);
其中:
stringObj是String 对象,是要被搜索的字符串;
参数regex是定义的RegExp对象实例,即正则表达式匹配模式;
index是返回的结果,成功搜索到匹配的字符时,返回第一个匹配字符的开始位置,否则返回-1。
search()方法通过正则表达式查找相应的字符串,只是判断有无匹配的字符串。如果查找成功,search()方法返回匹配串的位置,否则返回-1。search()方法和上面的test()方法有点相似,只是返回的结果不一样。search()方法使用实例如源程序14.4所示。
//源程序14.4
<html>
<head>
<title>search()方法</title>
</head>
<body bgcolor="lightgrey">
<script language="JavaScript" type="text/javascript">
<!--
var myStr="Search()方法是用来搜索字符串中与正则表达式匹配的子字符串的位置";
var regex = /字符/;
var index=myStr.search(regex);
if(index==-1)
alert("\n匹配结果:\n\n目标字符串中没有找到匹配的子串! \n");
else
alert("\n匹配结果:\n\n在目标字符串的第"+index+"个字符位置找到匹配模式: "+ regex.source+"\n");
-->
</script>
</body>
</html>
保存并运行上述代码,结果如图14.7所示。
在源程序14.4中把要查找的子串从“字符”改为“符字”,表达式如下:
var regex = /符字/;
再次运行程序,执行结果如图14.8所示,验证不成功匹配时,返回值为-1。

图14.7 search()方法成功匹配 图14.8 search()方法不成功匹配
14.4.6
match()方法
match()方法用来执行全局查找,并把查找结果存放在一个数组里。
其语法如下所示:
var result=stringObj.match(regex)
其中:
stringObj是String 对象,是要被搜索的字符串;
参数regex是定义的RegExp对象实例,即正则表达式匹配模式;
result是返回的结果,是一个包含搜索结果的数组,若不成功则返回null。
match()方法与上面介绍的exec()方法类似,返回的都是结果数组。Match()方法和exec()方法的比较如下:
参数不同,match方法以RegExp对象实例为参数,而exec()方法以字符串为参数;
如果正则表达式都没有设置全局标志(g),那么match()方法产生的结果与exec()方法产生的结果相同;
如果正则表达式设置了全局标志(g),则match()方法返回的数组中包含所有完整的匹配结果,数组元素依次是每个完整的匹配结果,而exec()方法返回的结果数组是查询结果与各个子匹配的结果。
下面通过一个实例融合使用match()和exec()方法,代码如源程序14.5所示。
//源程序14.5
<!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.0//EN"
"http://www.w3.org/TR/REC-html140/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Sample Page!</title>
<script language="JavaScript" type="text/javascript">
<!--
//模式匹配并输出结果
function testmatch()
{
var msg="\nmatch()方法和exec()方法比较 :\n\n";
//目标字符串
var myStr="如果在正则表达式中设置了全局标志(g)进行模式匹配,\n"
+"使用match()方法返回的数组中包含所有完整的匹配结果,\n"
+"而exec()方法返回的数组中包含各个子匹配的结果.";
//创建正则表达式对象
var regex = /(匹)配/g;
//使用exec()方法进行匹配
var array=regex.exec(myStr);
msg+="目标字符串 :\n"+myStr+"\n";
msg+="搜索子串 :\n"+regex+"\n";
if(array)
{
msg+="\nexec()方法搜索结果 : \n找到匹配子串!"
+"\n返回数组 :"+array
+"\n数组长度:"+array.length;
}
else
{
alert("使用exec()方法在目标字符串中未找到子串!");
return;
}
//使用match()方法
var newarray=myStr.match(regex);
if (newarray)
{
msg+="\nmatch()方法搜索结果 :\n找到匹配子串!"
+"\n返回数组 :"+newarray
+"\n 数组长度:"+newarray.length;
alert(msg);
}
else
{
alert("使用match()方法在目标字符串中未找到子串!");
return;
}
}
-->
</script>
</head>
<body>
<br>
<center>
<p>
match()方法和exec()方法的比较
</p>
<form onSubmit="return testmatch();">
<input type="submit" value="确定">
</form>
</center>
</body>
</html>
程序运行后,在原始页面中单击“确定”按钮,弹出警告框如图14.9所示。
exec()方法返回的数组元素有两个:“匹配,匹”,其中“匹配”是正则表达式匹配结果;而“匹”是子匹配结果。match()方法返回的数组元素有三个:“匹配,匹配,匹配”,即为全文所有的匹配结果。

图14.9 match()和exec()方法的比较
14.4.7
replace()方法
replace()方法是在一个字符串中通过正则表达式查找并替换相应的内容。但并不改变原来的字符串,只是重新生成了一个新的字符串。
其语法如下所示:
var newstr= stringObj.replace(regex, "expression");
其中:
stringObj 和regex分别为String和RegExp对象实例,与search()方法或者match()方法对应的参数相同;
参数expression是用于替换的字符串,如要把正则表达式查找的结果替换成“abc”,则expression为“abc”。也可以是一些特殊的字符组合,例如,要用正则表达式第一个子匹配字符来替换正则表达式,则expression可以写成“$1”;
newstr返回的结果,是完成替换后生成的新字符串。
考察源程序14.6。
//源程序14.6
<!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.0//EN"
"http://www.w3.org/TR/REC-html140/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Sample Page!</title>
<script language="JavaScript" type="text/javascript">
<!--
//模式匹配并输出结果
function testmatch()
{
var msg="\n使用replace()方法替换字符串 :\n\n";
var myStr="如果在正则表达式中设置了全局标志(g)进行模式匹配, \n"
+"则使用match()方法返回的数组中包含所有完整的匹配结果,\n"
+"而exec()方法返回的数组中包含各个子匹配的结果.";
//创建正则表达式对象
var regex=/数组/gi;
//使用replace()方法
var newStr=myStr.replace(regex,"结果");
msg+="原始字符串 :\n"+myStr+"\n\n";
msg+="操作语句 :\n"+"var newStr=myStr.replace(regex,''结果'');\n\n"
msg+="更新字符串 :\n"+newStr+"\n";
alert(msg);
}
-->
</script>
</head>
<body>
<center>
<p>
replace()方法
</p>
<form onSubmit="return testmatch();">
<input type="submit" value="确定">
</form>
</center>
</body>
</html>
程序运行后,在原始页面中单击“确定”按钮,弹出警告框如图14.10所示。

图14.10 使用replace()方法替换字符串
如果用到正则表达式的搜索结果,表达式中可以用存储的子匹配来表示,更改上述实例中的testmatch()函数为如下形式:
function testmatch()
{
var msg="\n使用replace()方法替换字符串 :\n\n";
var myStr="John Smith";
//创建正则表达式对象
var regex=/(\w+)\s(\w+)/;
//使用replace()方法
var newStr=myStr.replace(regex,"$2,$1");
msg+="原始字符串 :\n"+myStr+"\n\n";
msg+="操作语句 :\n"+"var newStr=myStr.replace(regex,''$2,$1''); \n\n"
msg+="更新字符串 :\n"+newStr+"\n";
alert(msg);
}
程序运行后,在原始页面中单击“确定”按钮,弹出如图14.11所示的警告框。
在原始字符串“John Smith”中, $1= John ,$2= Smith,所以 "$2, $1"= "Smith, John",得到替换的结果。

图14.11 使用匹配字符为replace()方法的参数替换字符串
注意:正则表达式中\w+匹配的是一串连续的字符,所以第一个\w+匹配的是John,第二个\w+匹配的是Smith。正则表达式的语法规则将在后续章节进行详细的介绍。
14.4.8
split()方法
split()方法是用来返回按照某种分割标志符将一个字符串拆分为若干个子字符串时所产生的子字符串数组。
其语法如下所示:
var array=stringObj.split(regex[,limit]);
其中:
stringObj是String对象实例,是要被分割的字符串;
regex是正则表达式对象,是作为分割标志符出现的,这里也可以直接是若干字符,直接组成分割字符标志;
参数limit限制返回的结果数组元素个数,是可选项,如果没有设置,默认为返回全部。
array是返回的结果数组,如果没有找到匹配的分割字符标志,返回一个字符串,那就是整个原字符串。
考察源程序14.7。
//源程序14.7
<!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.0//EN"
"http://www.w3.org/TR/REC-html140/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Sample Page!</title>
<script language="JavaScript" type="text/javascript">
<!--
//模式匹配并输出结果
function testmatch()
{
var msg="\n使用split()方法分割字符串 :\n\n";
var myStr="数学95;语文85;英语89;生物71";
//创建正则表达式对象
var regex=/;/;
//使用split()方法
var splitArray=myStr.split(regex);
msg+="原始字符串 :\n"+myStr+"\n\n";
msg+="操作语句 :\n"+"var splitArray=myStr.split(regex);\n\n"
msg+="结果数组 :\n";
for(i=0; i<splitArray.length; i++)
{
msg+="splitArray[" +i+ "] = "+splitArray[i]+"\n";
}
alert(msg);
}
-->
</script>
</head>
<body>
<center>
<p>split()方法</p>
<form onSubmit="return testmatch();">
<input type="submit" value="确定">
</form>
</center>
</body>
</html>
程序运行后,在原始页面中单击“确定”按钮,弹出警告框如图14.12所示。

图14.12 split()方法分割字符串
14.4.9
小结
本节详细介绍了正则表达式的七种标准操作方法:RegExp对象中的test()、exec()、compile()方法以及String对象中的search()、match()、replace()、split()方法;详细讲述了每种方法的语法结构以及使用方法,并举例说明,同时也比较了它们之间的异同。
在学习过程中,读者不难发现,如果正则表达式构造正确,这些方法操作起来都不难。但如何去准确地构造需要的正则表达式却是困难的,特别是复杂的正则表达式,因为这些表达式不再由简单的字符构成,如前面列举的电话号码正则表达式实例。下面详细介绍正则表达式的语法法则。






