JavaScript高级程序设计第5章读书笔记(17)

为简化替换子字符串的操作,ECMAScript提供了replace()方法。它接收2个参数:第一个参数可以是一个RegExp对象或者一个字符串(这个字符串不会被转换成正则表达式),第二个参数可以是一个字符串或者一个函数。如果第一个参数是字符串,那么只会替换第一个子字符串。要想替换所有的子字符串,必须提供一个正则表达式,而且要指定全局(g)标志。比如:

如果第二个参数是字符串,还可以使用一些特殊的字符序列,将正则表达式操作得到的值插入到结果字符串中。下表列出了ECMAScript提供的这些特殊字符序列。

字符序列 替换文本
$$ $
$& 匹配整个模式的子字符串。与RegExp.lastMatch的值相同
$’ 匹配的子字符串之前的子字符串。与RegExp.leftContext的值相同
$` 匹配的子字符串之后的子字符串。与RegExp.rightContext的值相同
$n 匹配第n个捕获组的子字符串,其中n等于0~9。例如,$1是匹配第一个捕获组的子字符串,$2是匹配第2个捕获组的子字符串,以此类推。如果正则表达式中没有定义捕获组,则使用空字符串
$nn 匹配第nn个捕获组的子字符串,其中nn等于01~99。例如,$01是匹配第一个捕获组的子字符串,$02是匹配第二个捕获组的子字符串,以此类推。如果正则表达式中没有定义捕获组,则使用空字符串

replace()方法的第二个参数也可以是一个函数。在只有一个匹配项(即与模式匹配的字符串)的情况下,会向这个函数传递3个参数: 模式的匹配项、模式匹配项在字符串中的位置、原始字符串。在正则表达式中定义了多个捕获组的情况下,传递给函数的参数依次是模式的匹配项、第一个捕获组的匹配项、第二个捕获组的匹配项…,但最后2个参数仍然分别是模式的匹配项向字符串中的位置、原始字符串。这个函数应该返回一个字符串,表示应该被替换的匹配项使用函数作为replace()方法的第二个参数可以实现更加精细的替换操作,比如:

split()

split()方法,可以基于指定的分隔符将一个字符串分割成多个子字符串,并将结果放在一个数组中。分隔符可以是字符串,也可以是一个RegExp对象。split()方法可以接受可选的第二个参数,用于指定数组的大小,以便确保返回的数组不会超过既定的大小。比如:

注意,上例中,最后一次调用split()返回的数组中,第一项和最后一项是两个空字符串。这是因为通过正则表达式指定的分隔符出现在了字符串的开头(“red”)和末尾(“yellow”)。

对split()中正则表达式的支持因浏览器而异。尽管对于简单模式没有什么差别,但对于未发现匹配项以及带有捕获组的模式,匹配的行为就大不相同了。比如:

  • IE8以及之前版本会忽略捕获组。ECMA-262规定应该把捕获组拼接到结果数组中。IE9能正确地在结果中包含捕获组。
  • Firefox 3.6以及之前版本在捕获组未找到匹配项时,会在结果数组中包含空字符串;ECMA-262规定没有匹配项的捕获组在结果数组中应该用undefined表示。

在正则表达式中使用捕获组时还有其他微妙的差别,一定要多测试。
参考: http://blog.stevenlevithan.com/archives/cross-browser-split