replace
方法
字符串有一个replace
方法,该方法可用于将字符串中的一部分替换为另一个字符串。
console.log("papa".replace("p", "m"));
// → mapa
该方法第一个参数也可以是正则表达式,这种情况下会替换正则表达式首先匹配的部分字符串。若在正则表达式后追加g
选项(全局,Global),该方法会替换字符串中所有匹配项,而不是只替换第一个。
console.log("Borobudur".replace(/[ou]/, "a"));
// → Barobudur
console.log("Borobudur".replace(/[ou]/g, "a"));
// → Barabadar
如果 JavaScript 为replace
添加一个额外参数,或提供另一个不同的方法(replaceAll
),来区分替换一次匹配还是全部匹配,将会是较为明智的方案。遗憾的是,因为某些原因 JavaScript 依靠正则表达式的属性来区分替换行为。
如果我们在替换字符串中使用元组,就可以体现出replace
方法的真实威力。例如,假设我们有一个规模很大的字符串,包含了人的名字,每个名字占据一行,名字格式为“姓,名”。若我们想要交换姓名,并移除中间的逗号(转变成“名,姓”这种格式),我们可以使用下面的代码:
console.log(
"Liskov, Barbara\nMcCarthy, John\nWadler, Philip"
.replace(/(\w+), (\w+)/g, "$2 $1"));
// → Barbara Liskov
// John McCarthy
// Philip Wadler
替换字符串中的$1
和$2
引用了模式中使用圆括号包裹的元组。$1
会替换为第一个元组匹配的字符串,$2
会替换为第二个,依次类推,直到$9
为止。也可以使用$&
来引用整个匹配。
第二个参数不仅可以使用字符串,还可以使用一个函数。每次匹配时,都会调用函数并以匹配元组(也可以是匹配整体)作为参数,该函数返回值为需要插入的新字符串。
这里给出一个小示例:
let s = "the cia and fbi";
console.log(s.replace(/\b(fbi|cia)\b/g,
str => str.toUpperCase()));
// → the CIA and FBI
这里给出另一个值得讨论的示例:
let stock = "1 lemon, 2 cabbages, and 101 eggs";
function minusOne(match, amount, unit) {
amount = Number(amount) - 1;
if (amount == 1) { // only one left, remove the 's'
unit = unit.slice(0, unit.length - 1);
} else if (amount == 0) {
amount = "no";
}
return amount + " " + unit;
}
console.log(stock.replace(/(\d+) (\w+)/g, minusOne));
// → no lemon, 1 cabbage, and 100 eggs
该程序接受一个字符串,找出所有满足模式“一个数字紧跟着一个单词(数字和字母)”的字符串,返回时将捕获字符串中的数字减一。
元组(\d+)
最后会变成函数中的amount
参数,而·(\w+)元组将会绑定
unit。该函数将
amount转换成数字(由于该参数是
\d+`的匹配结果,因此此过程总是执行成功),并根据剩下 0 还是 1,决定如何做出调整。