在 JS 沒有提供一種簡(jiǎn)便的方法來替換所有指定字符。 在 JAVA 中有一個(gè) replaceAll() ,replaceAll(String regex, String replacement))方法使用給定的參數(shù) replacement 替換字符串所有匹配給定的正則表達(dá)式的子字符串。
在 JS 最新的提案
String.prototype.replaceAll() 中,它將replaceAll()方法用于字符串。
在該提案還沒出來之前,我們來看看在 JS 中有哪些方法可以實(shí)現(xiàn) reaplceAll 的效果。
第一種:使用 split 和 join 的方法
這種方法,主要包含二個(gè)階段:
- 使用 split 方法,根據(jù)指定的字符將字符串分成多個(gè)部分。
- 然后使用 join 方法將分割的多個(gè)部分連接在一直,并在它們之間插入指定的字符。
例如,我們將字符串'1+2+3'中的+替換為-。首先,通過split方法根據(jù) +分割符將'1+2+3'分開,得到['1','2','3']。然后通過 join 方法并指定連接字條-,得到結(jié)果'1-2-3'。示例如下:
const search = 'duck';
const replaceWith = 'goose';
const result = 'duck duck go'.split(search).join(replaceWith);
result; // => 'goose goose go'
'duck duck go'.split('duck')將字符串分割成幾段:['', ' ', ' go']。['', ' ', ' go'].join('goose') 在元素之間插入'goose'并連接起來,得到'goose goose go'。
最后我們把這種方式封裝成一個(gè)幫助函數(shù) replaceAll:
function replaceAll(string, search, replace) {
return string.split(search).join(replace);
}
replaceAll('abba', 'a', 'i'); // => 'ibbi'
replaceAll('go go go!', 'go', 'move'); // => 'move move move!'
replaceAll('oops', 'z', 'y'); // => 'oops'
這種方法需要將字符串轉(zhuǎn)換為數(shù)組,然后再轉(zhuǎn)換回字符串。這是一種變通方法,但不是一個(gè)好的解決方案。
2. 使用全局正則表達(dá)式replace()
String.prototype。replace(regExp, replaceWith)搜索正則表達(dá)式regExp出現(xiàn)的情況,然后使用replaceWith字符串替換所有匹配項(xiàng)。
必須啟用正則表達(dá)式上的全局標(biāo)志,才能使replace()方法替換模式出現(xiàn)的所有內(nèi)容,我們可以這樣做:
- 在正則表達(dá)式文字中,將g附加到標(biāo)志部分:/search/g。
- 對(duì)于正則表達(dá)式構(gòu)造函數(shù),使用 flags 參數(shù):new RegExp('search', 'g')
我們把所有的duck換成goose:
const searchRegExp = /duck/g
const replaceWith = 'goose'
const result = 'duck duck go'.replace(searchRegExp, replaceWith)
result // 'goose goose go'
正則表達(dá)式文字/duck/g與'duck'字符串匹配,并且啟用了全局模式。
'duck duck go'.replace(/duck/g, 'goose')用'goose'替換所有匹配/duck/g字符串。
通過向正則表達(dá)式添加i標(biāo)志,可以忽略大小寫:
const searchRegExp = /duck/gi;
const replaceWith = 'goose';
const result = 'DUCK duck go'.replace(searchRegExp, replaceWith);
result; // => 'goose goose go'
再次查看正則表達(dá)式:/duck/gi。 正則表達(dá)式啟用了不區(qū)分大小寫的搜索:i和全局標(biāo)志g。 /duck/gi匹配'duck',以及'DUCK','Duck'等。
'DUCK duck go'.replace(/duck/gi, 'goose')以不區(qū)分大小寫的方式用'goose'替換了/duck/gi`所匹配到的結(jié)果。
雖然正則表達(dá)式替換了所有出現(xiàn)的字符串,但在我看來,這種方法過于繁瑣。
2.1 字符串中的正則表達(dá)式
當(dāng)在運(yùn)行時(shí)確定搜索字符串時(shí),使用正則表達(dá)式方法不方便。 從字符串創(chuàng)建正則表達(dá)式時(shí),必須轉(zhuǎn)義字符-[] / {}()* +? 。 ^ $ |,示例如下:
const search = '+'
const searchRegExp = new RegExp(search, 'g') // // 拋出 SyntaxError 異常
const replaceWith = '-'
const result = '5+2+1',replace(searchRegExp, replaceWith )
上面的代碼片段嘗試將搜索字符串'+'轉(zhuǎn)換為正則表達(dá)式。 但是'+'是無效的正則表達(dá)式,因此會(huì)引發(fā)SyntaxError: Invalid regular expression: /+/異常。
2.2 字符串的 replace() 方法
如果replace(search, replaceWith)的第一個(gè)參數(shù)是字符串,那么該方法只替換search的第一個(gè)結(jié)果。
const search = 'duck';
const replaceWith = 'goose';
const result = 'duck duck go'.replace(search, replaceWith);
result; // => 'goose duck go'
'duck duck go'.replace('duck','goose')僅將'duck'的首次出現(xiàn)替換為'goose'。
3.replaceAll() 方法
最后,新的提案
String.prototype.replaceAll()(在第3階段)將replaceAll()方法引入到 JavaScript 的字符串中。
replaceAll(search, replaceWith)字符串方法用replaceWith替換所有的search字符串,沒有任何變通方法。
我們把所有的duck換成goose:
const search = 'duck'
const replaceWith = 'goose';
const result = 'duck duck go'.replaceAll(search, replaceWith);
result; // => 'goose goose go'
'duck duck go'.replaceAll('duck', 'goose')將所有出現(xiàn)的'duck'字符串替換為'goose',這是簡(jiǎn)單明了的解決方案。
3.1 replaceAll()與replace()的區(qū)別
字符串方法replaceAll(search, replaceWith)和replace(search, replaceWith)的行為方式是一樣的,除了兩件事:
- 如果search參數(shù)是一個(gè)字符串,那么replaceAll()用replaceWith替換所有出現(xiàn)的search,而replace()只替換第一次出現(xiàn)的search。
2.如果search參數(shù)是一個(gè)非全局正則表達(dá)式,那么replaceAll()將拋出一個(gè)TypeError 異常。
4. 總結(jié)
替換所有出現(xiàn)的字符串應(yīng)該很容易。 但是,JavaScript 很久一段時(shí)間沒有提供這種方法。
一種方法是通過搜索字符串將字符串拆分為多個(gè)塊,將字符串重新連接,然后在塊之間放置替換字符串:string.split(search).join(replaceWith)。 這種方法有效,但是很麻煩。
另一種方法是將String.prototype.replace()與啟用了全局搜索的正則表達(dá)式一起使用:string.replace(/SEARCH/g, replaceWith)。
不幸的是,由于必須轉(zhuǎn)義正則表達(dá)式的特殊字符,因此在運(yùn)行時(shí)無法輕松地從字符串生成正則表達(dá)式。 處理正則表達(dá)式以簡(jiǎn)單地替換字符串的方法非常麻煩。
最后,
String.prototype.replaceAll()方法可以輕松地直接替換所有出現(xiàn)的字符串:string.replaceAll(search, replaceWith)。 這是第3階段的提案,但希望很快就會(huì)納入新的JavaScript標(biāo)準(zhǔn)。
我的建議是使用replaceAll()來替換字符串。但你需要一個(gè)polyfill來使用這個(gè)方法。
你還知道其他替換所有字符串出現(xiàn)的方法嗎?歡迎留言討論。
作者: Dmitri Pavlutin 譯者:前端小智 來源:dmitripavlutin
原文:
https://dmitripavlutin.com/replace-all-string-occurrences-javascript/