本篇介绍 ES2021 (ES12) 提供的 String.prototype.replaceAll()
。
将一个字串中的指定子字串,取代成另一个字串,是很常见的字串处理情境。
例如:要将 URL 的 query 字串 q=query+string+parameters
中的 +
字元替换成空白字元:
// 原字串
'q=query+string+parameters'
// 替换成
'q=query string parameters'
常见有以下作法:
String.prototype.replace()
String.prototype.split()
+ Array.prototype.join()
下面分别说明这两种作法的小问题。
String.prototype.replace()
若要一次替换多个子字串,String.prototype.replace()
的第一个参数只能使用设定 global
flag 的 RegExp,而不是用字串。因为字串只能替换第一个子字串,不能一次替换多个子字串。
let query = 'q=query+string+parameters';
let queryWithSpaces = query.replace(/\+/g, ' ');
console.log(queryWithSpaces);
// q=query string parameters
这种方法的缺点是要用 RegExp,并且是转义过的字元,像此范例用的是转义过的 +
字元 (因为在 RegExp 的 pattern 中,+
有特殊的意义,代表 match 一个以上)。
String.prototype.split()
+ Array.prototype.join()
另一种常见的作法是同时使用 String.prototype.split()
和 Array.prototype.join()
let query = 'q=query+string+parameters';
let queryWithSpaces = query.split('+').join(' ');
console.log(queryWithSpaces);
// q=query string parameters
这种方法虽然可以不用处理跳脱字元 (escaping),但需要先将字串拆成包含多个字串的阵列,然後再将这些字串拼起来。
所以可以看到以上这些方法的小问题,就是不够直觉。原本只是想将所有的 +
字元,全部改为空白的简单需求,但因为 JavaScript 过去的限制,只能用一些独特的小技巧才能处理 QQ。
那有没有更直觉的作法?这就是本篇要介绍的 String.prototype.replaceAll()
派上用场的时刻!
String.prototype.replaceAll()
把前面的范例换成 String.prototype.replaceAll()
:
let query = 'q=query+string+parameters';
let queryWithSpaces = query.replaceAll('+', ' ');
console.log(queryWithSpaces);
// q=query string parameters
就这样!很简单吧!完全不用说明你就会了 XD
String.prototype.replace()
vs. String.prototype.replaceAll()
两者的 signature 一样 (即参数名称、参数数量一样):
String.prototype.replace(searchValue, replaceValue)
String.prototype.replaceAll(searchValue, replaceValue)
但两者的行为有些不同:
searchValue
是字串时:
replace()
只会替换第一个 searchValue
replaceAll()
会替换所有 searchValue
searchValue
不是设定 global
flag 的 RegExp 时:
replace()
只会替换第一个 searchValue
replaceAll()
会抛出 TypeError
exception,因为要避免与 replaceAll()
的行为不符合 (即不是全部替换)let query = 'q=query+string+parameters';
query.replaceAll(/\+/, ' ');
// TypeError: String.prototype.replaceAll called with a non-global RegExp argument
若 searchValue
是设定 global
flag 的 RegExp 时,两着的行为一样:
let query = 'q=query+string+parameters';
let queryWithSpaces1 = query.replace(/\+/g, ' ');
console.log(queryWithSpaces1);
// q=query string parameters
let queryWithSpaces2 = query.replaceAll(/\+/g, ' ');
console.log(queryWithSpaces2);
// q=query string parameters
虽然两者的行为一致,但应该很少会在
replaceAll
使用 RegExp 吧?
String.prototype.replaceAll
| 2ality
<<: op.26 《全领域》-全域开发实战 - 居家植物盆栽 Mvt I (NodeMCU & MQTT)
所有的网站大概可以分成两类:静态网页、动态网页,静态网页顾名思义就是静止的网页,不会去太频繁的更新内...
计算属性(Computed Property) 当我们今天想针对某一变数做运算或是处理时,可以透过模...
Backtracking:通常是用在需要纪录路径的 DFS 时。 往前搜寻,发现目前的元素不符合条件...
在ERP体系内,除了一般表格之外,就剩下树状结构了:部门组织、产品结构、销售网路等等,都是透过标定...
一、前言 在 JavaScript 的世界里有变数,那初学者们也知道 CSS (阶层式样式表,C...