String类型定义了几个用于在字符串中匹配模式的方法。第一个方法就是macth(),在字符串上调用这个方法,本质上与调用RegExp()的exec()方法相同。match()方法只接收一个参数,要么是一个正则表达式,要么是一个RegExp()对象。例如:
var text="cat,bat,sat,fat"; var pattern=/.at/; //与pattern.exec(text)相同 var matches=text.match(pattern); alert(matches.index);//0 alert(matches[0]);//"cat" alert(pattern.lastIndex); //0
这个例子的match()方法 了一个数组;如果是调用RegExp对象的exec()方法并传递本例中的字符串作为参数,那么也会得到与此同时的数组:数组的第一项是是与整个模式匹配的字符串,之后的每一项(如果有)保存着与正则表达式中的捕获组 匹配的字符串。
另一个用于查找模式的方法是search()。这个方法的唯一参数与match()方法的参数相同:由字符串或RegExp对象指定的一个正则表达式。search()方法返回字符串中的第一个匹配项的索引;如果没有找到匹配项,则返回-1。而且,search()方法始终是从字符串开头向后查找模式。例如:
var text="cat,bat,sat,fat"; var pos=text.search(/at/); alert(pos);//1
这个例子中的search()方法返回1,即“at”在字符串中第一次出现的位置。
为了简化替换子字符串的操作,ECMAScript提供了replace()方法。这个方法接收两个参数:第一个参数可以是一个RegExp对象或者一个字符串(这个字符串不会被转换成正则表达式),第二个参数可以是字符串或者一个函数。如果第一个参数是字符串,那么只会替换第一个子字符串。要想替换所有的字符串,就需要提供一个正则表达式,而且要指定全局(g)标志,例如:
var text="cat,bat,sat,fat"; var result=text.replace("at","ond"); alert(result);//"cond,bat,sat,fat" result=text.replace(/at/g,"ond"); alert(result);//"cond,bond,sond,fond"
在这例子中,首先出入replace()方法的是字符串“at”和需要替换成的字符串“ond”。替换的结果是把“cat”替换成了“cond”,但字符串中的其他字符并没有影响。然后,通过将第一个参数修改为带有全局标志的正则表达式,就将字符串中全部带有“at”的字符替换成了“ond”。
如果第二个参数是字符串,那么还可以使用一些特殊字符序列,将正则表达式操作得到的值插入到结果中去。下表列出了ECMAScript提供的这些特殊字符序列。
字符序列 | 替换文本 |
$$ | $ |
$& | 匹配整个模式的字符串。与RegExp.lastMatch的值相同。 |
$‘ | 匹配的子字符串之前的子字符串。与RegExp.leftContext值相同。 |
$` | 匹配的子字符串之后的子字符串。与RegExp.rightContext值相同。 |
$n |
匹配第n个捕获的子字符串,其中n等于0~9。例如,$1是匹配第一个捕获组的子字符串,$2是匹配第二个捕获组的子字符串,以此类推。如果正则表达式中没有定义捕获组,则使用空字符串 |
$nn |
匹配第nn个捕获组的子字符串,其中nn等于01~99。例如,$01是匹配第一个捕获组的子字符串,$02是匹配第二个捕获组的子字符串,以此类推。如果正则表达式中没有定义捕获组,则使用空字符串。 |
通过这些特殊的字符序列,可以使用最近一次匹配结果中的类容,例如:
var text="cat,sat,bat,fat"; result=text.replace(/(.at)/g,"word($1)"); alert(result);//word(cat),word(sat),word(bat),word(fat)
在此,每个以“at”结尾的单词都被替换了,替换结果是以“word”后跟一对圆括号,而括号中是被字符序列$1所替换的单词。
replace()方法的第二个参数也可以是个函数。在只有一个匹配项(即与模式匹配的字符串)的情况下,会向这个函数传递3个参数:模式匹配项,模式匹配项在字符串中的位置和原始字符串。在正则表达式中定义了多个捕获组的情况下,传递给函数的参数依次是模式的匹配项、第一个捕获组的匹配项、第二个捕获组的匹配项......,但是最后两个参数仍然分别是模式的匹配项在字符串中位置和原始字符串。这个函数应该返回一个字符串,表示应该被替换的匹配项。使用函数作为replace()方法的第二个参数可以实现更加精细的替换操作,例如:
function htmlEscape(text) { return text.replace(/[<>"&]/g, function(match,pos,originalText) { switch(match) { case "<": return "<"; case ">": return ">"; case "&": return "&"; case "\": return """; } }); } alert(htmlEscape("<p class=\"greeting\">Hello world !</p>")); //<p class="greeting">Hello world !</p>
这里,我们为插入HTML代码定义了函数htmlEscape(),这个函数能够转义4个字符:小于符号、大于符号、和号以及双引号。实现这种转义的最简单方式,就是使用正则表达式查找者几个字符,然后定义一个能针对每个匹配的字符返回特定的HTML实体的函数。
最后一个与模式匹配有关的方法是split(),这个方法可以基于指定的分隔符将一字符串分割成多个字符串,并将结果放在一个数组中。分隔符可以是字符串,也可以是一个RegExp对象(这个方法不会将字符串看成正则表达式)。split()方法可以接受可选的第二个参数,用于指定数组的大小,以便于确保返回的数组不会超过既定大小。离去:
var colorText="red,blue,green,yellow"; var colors1=colorText.split(",");//["red","blue","green","yellow"] var colors2=colorText.split(",",2);//["red","blue"] var colors3=colorText.split(/[^\,]+/);//["",",",",",",",""]
在上例子中,colorText是逗号分隔的颜色字符串。基于该字符串调用了split(",")会得到一个包含其中颜色名的数组,用于分隔字符串的分隔符是逗号。为了将数组截短,让它只包含两项,可以为split()方法传递第二个参数2。最后通过使用正则表达式,还可以取得包含逗号字符的数组。需要注意的是,在最后一次调用split()返回的数组中,第一项和最后一项是两个空字符串。之所以会这样,是因为通过正则表达式指定的分隔符出现了字符串的开头(即子字符串“red”)和末尾(即子字符串“yellow”)。
对split()中正则表达式的支持因浏览器而异。尽管对于简单的模式没有什么差别,但对于未发现匹配项以及带有捕获组的模式,匹配的行为就不大相同了。以下是几种常见的差别:
- IE8 以及之前版本会忽略捕获组。ECAM-262规定应该把捕获组拼接到结果数组中。IE9能正确的在结果中包含捕获组。
- FF3.6以及之前的版本在捕获组未找到匹配项时,会在结果数组中包含空字符串;ECAM-262规定没有匹配项的捕获组在结果数组中应该用undefined表示。
在正则表达式中使用捕获组时还有其他微妙的差别。在使用这种正则表达式时,一定要在各种浏览器下多做一些测试。