使用字符串的replace()方法可以实现字符串替换操作。该方法包含两个参数:
第一个: 表示执行匹配的正则表达式,也可以传递字符串
第二个: 表示准备代替匹配的子字符串
var s = "index.html";
var b = s.replace("html", "htm");
replace()方法同时执行查找和替换两个操作。该方法将在字符串中查找与正则表达式相匹配的子字符串,然后调用第二个参数值或替换这些子字符串。
如果正则表达式具有全局性质,那么将替换所有匹配子字符串,否则,只替换第1个匹配子字符串。
在replace()方法中约定了一个特殊的字符“$”,如果这个美元符号附加了一个序号,就表示引用正则表达式中匹配的子表达式存储的字符串。
示例:
var s = "javascript";
var b = s.replace(/(java)(script)/, "$2-$1");
document.write(b); //"script-java"
在上面的代码中,正则表达式/(java)(script)/中包含两对小括号,按顺序排列,其中第一对小括号表示第一个子表达式,第二对小括号表示第二个子表达式,在replace()方法的参数中可以分别使用字符串 “$1” 和 “$2” 来表示对它们匹配文本的引用,当然它们不是标识符,仅是一个标记,所以不可以作为变量参与计算。
美元符号与其他特殊字符组合的含义:
由于字符串“$&”在replace()方法中被约定为正则表达式所匹配的文本,因此利用它可以重复引用匹配的文本,从而实现字符串重复显示效果。其中" /.*/ "表似乎完全匹配字符串
var s = "javascript";
var b = s.replace(/.*/, "$&$&");//"javascriptjavascript"
匹配左侧文本:字符"$&“代表匹配字符串“script”,字符” $ “代表匹配文本左侧文本"java”
var s = "javascript";
var b = s.replace(/script/, "$& != $`" );//"javascript != java
匹配右侧文本:其中字符"$&"代表匹配字符串“java”,字符“ $ ”代表匹配文本右侧文本“script”。然后用“ $& $’ is”所代表的字符串“Javascript is” 替换原字符串中的“java”子字符串,即组成一个新的字符串“javascript is script”。
var s = "javascript";
var b = s.replace(/java/, "$&$' is ");//"javascript is script"
在ECMAScript3中明确规定,replace()方法的第二个参数建议使用函数,而不是字符串(当然字符串也可以用,没毛病),JavaScript1.2实现了对这个特性的支持。
这样当replace()方法执行匹配时,每次都会调用该函数,函数的返回值将作为替换文本执行匹配操作,同时函数可以接收以 $ 为前缀的特殊字符组合,用来对匹配文本的相关信息进行引用。
var s = 'script language = "javascript" type= " text / javascript"';
var f = function($1){
return $1.substring(0, 1).toUpperCase() + $1.substring(1);
}
var a = s.replace(/(\b\w+\b)/g, f);
alert(a);
函数f()的参数$1表示正则表达式/(\b\w+\b)/g每次匹配的文本。然后再函数体内对这个匹配文本进行处理,截取其首字母并转换为大写形式,之后返回新处理的字符串。replace()方法能够在原文本中使用这个返回的新字符串替换每次匹配的子字符串。
对于上面的例子,可以使用小括号来获取更多匹配文本的信息。
例如:直接利用小括号传递单词的首字母,然后进行大小写转换处理。
var s = 'script language = "javascript" type= " text / javascript"';
var f = function($1, $2, $3){
return $2.toUpperCase() + 43;
}
var a = s.replace(/\b(\w)(\w*)\b/g, f);//Script Language = "Javascript" Type = " Text /Javascript"
在函数f()中,第一个参数表示每次匹配的文本,第二个参数表示第一个小括号的子表达式所匹配的文本,即单词的首字母,第二个参数表示第二个小括号的子表达式所匹配的文本。
实际上,replace()方法的第二个参数的函数的参数是含蓄的,即使不传递任何形参,replace()方法依然会向它传递多个实参,这些实参都包含一定的意思,具体如下:
可以将上例修改为如下形式:
var f = function(){
return arguments[1].toUpperCase(0 + arguments[2];
}
如果不为函数传递形参,直接调用函数的arguments属性,同样能偶读取到正则表达式中相关匹配文本的信息你。
var s = 'script language = "javascript" type= " text / javascript"';
var f = function(){
for(var i = 0; i < arguments.length; i++){
alert("第" + (i + 1) + "个参数的值:" + arguments[i]);
}
}
var a = s.replace(/\b(\w)\b/g/, f);
在函数体中,使用for循环遍历arguments属性,每次匹配单词时,都会弹出5次提示信息,分别显示上面所列的匹配文本信息。其中,arguments[1]、arguments[2]会根据每次匹配文本不同,分别显示当前匹配文本中子表达式匹配的信息,arguments[3]显示当前匹配单词的下标位置。而arguments[0]总是显示每次匹配的单词,arguments[4]总是显示被操作的字符串。
例子:自动提取字符串中的分数,汇总后计算平均分
var s = "张三56分,李四74分,王五92分,赵六84分";
var a = s.match(/\d+/g), sum = 0;
for(var i = 0; i < a.length; i++){
sum += parseFloat(a[i]);
};
var avg = sum / a.length;
function f(){
var n = parseFloat(arguments[1]);
return n + "分" + "(" + ((n > avg) ? ("超出平均分" + (n - avg)) : ("低于平均分" + (avg - n))) + "分)";
}
var s1 = s.replace(/(\d+)分/g, f);document.write(s1);
在上面的示例中,遍历数组时不能够使用for in语句,因为这个数组中还存储着其他相关的匹配文本信息。应该使用for语句来实现。由于截取的数字都是字符串类型,应把它们都转换为数值类型,否则会被误解,例如把数字连接在一起,或者按字母顺序进行比较等。