iT邦幫忙

0

js過濾字串

想請問各位大佬
有一個題目是
let word = ['靠','乾','它螞的']
若有一個函式是
function Word(word){

}

Word('靠,它螞的今天運氣超差,乾');
若參數的文字裡有包括陣列裡的字
輸出會變成 *** ,今天運氣超差,
大概會用什麼方式來處理/images/emoticon/emoticon41.gif

看更多先前的討論...收起先前的討論...
淺水員 iT邦大師 6 級 ‧ 2021-01-13 23:38:35 檢舉
要被取代的文字數量大概多少呢?
建議下方froce為正解,用正則代換可以用array置換
ccutmis iT邦高手 2 級 ‧ 2021-01-14 10:18:32 檢舉
我覺得 兩位邦友的回答都是正解 但是就執行效能上來看 我會投array + replace 一票
你想想當要過濾的陣列元素多達幾十個的時候 用它們去做正則的OR判斷...
程式碼縮短是很酷 但是要思考的是這會不會變成未來的技術債
無意筆戰,只是replaceAll在背景也是做著forEach的事,效能應該是一樣的,程式寫的少,對於後面接手的人而言,反倒是比較容易閱讀吧
(個人觀點)
https://ithelp.ithome.com.tw/articles/10252086
淺水員 iT邦大師 6 級 ‧ 2021-01-14 10:41:14 檢舉
是還有其他方式
因為樓主沒啥回應我就只貼連結了
這邊有個 js 專案是用字詞取代做繁簡體轉換
https://github.com/nk2028/opencc-js
做法是先把所有字詞轉換成樹狀結構
提供之後在掃描文章時對照用
可以降低時間複雜度
rogeryao iT邦超人 8 級 ‧ 2021-01-14 11:15:17 檢舉
改用 '靠靠,靠今天運氣超差,乾' 試試吧
ccutmis iT邦高手 2 級 ‧ 2021-01-14 11:24:29 檢舉
不是我要筆戰 我只是提出我的土法煉鋼的心得

二樓用的是 array loop+replace 跟replaceAll是不同的東西
效能的部份我是認為以這邊的情況來說replace是比regex好 當然我懶得去測試了

"程式寫的少,對於後面接手的人而言,反倒是比較容易閱讀吧 "
那把全部程式碼都縮到只有一行不就最好讀? 真有趣的觀點...
通靈亡 iT邦高手 1 級 ‧ 2021-01-14 11:30:15 檢舉
插播一下 replaceAll() 跟 replace() 的差異,兩者都可以達到相同的作用

String.replaceAll() 是比較新的方法,會取代所有符合規則的字串
但只支援較新的瀏覽器,不支援較舊的Chrome,FF 與 IE11以前的瀏覽器
https://caniuse.com/?search=replaceAll

String.replace() 是傳統的方法,預設會取代第一個符合規則的文字
可以透過正規表達式達到replaceAll()的功能,支援IE與較舊版的瀏覽器
https://caniuse.com/?search=replace

Demo:
https://jsfiddle.net/tghs25de/
ccutmis iT邦高手 2 級 ‧ 2021-01-14 11:47:34 檢舉
不用字串replace replaceAll regex 也不需要建字典 的範例:
function Word2(word){
let finalword='';
const filterWords = ['靠','乾'];
for (i=0;i<word.length;i++){
finalword+=filterWords.includes(word[i])?"***":word[i];
}
return finalword;
}
console.log(Word2('靠乾靠靠今天靠運氣超差,乾'));
這是一個題目 文字數量就是題目上那樣哈哈 抱歉現在才看到
froce iT邦大師 1 級 ‧ 2021-01-14 12:53:23 檢舉
RegExp(blacklist.join("|"), "gm")

後面的gm是選項,應該用replace就能全部取代了。

簡單的話用正則是比較好寫啦,複雜的話可能得靠上面繁簡轉換的方式。
ccutmis iT邦高手 2 級 ‧ 2021-01-14 13:02:33 檢舉
大師說的是。
扯個提外話 在這邊一個討論可以得到多種解決方案 樓主這提問很值啊 :D
賺到>< 太多大老啦~~哈哈
froce iT邦大師 1 級 ‧ 2021-01-14 15:11:19 檢舉
我是嘴砲的大師...XD
通靈亡 iT邦高手 1 級 ‧ 2021-01-14 15:33:12 檢舉
>無意筆戰,只是replaceAll在背景也是做著forEach的事
這邊要補充一個 japhenchen 提到的地方
replaceAll 的原理其實是以replace() + global 的正規表達式

詳情可參考 TC39 的 github:String.prototype.replaceAll proposal
https://github.com/tc39/proposal-string-replaceall

> Notably, String.prototype.replaceAll behaves just like String.prototype.replace if searchValue is a global regular expression.

想了解 TC39 的可參考 japhenchen 上面引用的鐵人賽系列第一篇
https://ithelp.ithome.com.tw/articles/10237660

>Ecma 標準是由各種技術委員會管理的,而 TC39 就是其中一個 TC,是 Technical Committee (技術委員會) 的縮寫,TC 會處理特定的領域或主題。

>TC39 主要負責將通用、跨平台與 vendor 無關的程式語言 ECMAScript 標準化,包括語言的 syntax、semantics 和 library 以及支援該語言的補充技術。
有神快敗
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

4
通靈亡
iT邦高手 1 級 ‧ 2021-01-13 23:03:34

解法1

使用array.forEach + replace依序過濾 filterWords 陣列當中的文字

function Word(word){
  const filterWords = ['靠','乾']
  
  filterWords.forEach(filterWord => {
    filterRegExp = new RegExp(filterWord, 'g')
  	word = word.replace(filterRegExp, '***')
  })
  
  return word
}

console.log(Word('靠,今天運氣超差,乾'));

https://jsfiddle.net/bwsmrndy/

解法2

使用array.reduce + replace 依序過濾 filterWords 陣列當中的文字

function Word(word){
  const filterWords = ['靠','乾']
  
  return filterWords.reduce((allWords, filterWord) => {
    filterRegExp = new RegExp(filterWord, 'g')
    return allWords.replace(filterRegExp, '***')
  }, word)
}

console.log(Word('靠,今天運氣超差,乾'));

https://jsfiddle.net/Lskq35px/

解法3

使用for...of + replace 依序過濾 filterWords 陣列當中的文字

function Word(word){
  const filterWords = ['靠','乾']
  
  for (let filterWord of filterWords) {
    filterRegExp = new RegExp(filterWord, 'g')
  	word = word.replace(filterRegExp, '***')
  }
  
  return word
}

console.log(Word('靠,今天運氣超差,乾'));

https://jsfiddle.net/twjk65r0/

感謝大佬!!!/images/emoticon/emoticon41.gif

ccutmis iT邦高手 2 級 ‧ 2021-01-14 11:38:27 檢舉

rogeryao: 改用 '靠靠,靠今天運氣超差,乾' 試試吧

幫補一個土法鍊鋼修正bug的範例:

<script>
function Word(word){
  const filterWords = ['靠','乾']
  
  filterWords.forEach(filterWord => {
    word = word.replace(filterWord, '***')
  })
  
  return word
}
console.log(Word('靠乾靠靠今天靠運氣超差,乾'));

function Word2(word){
    let finalword='';
    const filterWords = ['靠','乾'];
    for (i=0;i<word.length;i++){
        finalword+=filterWords.includes(word[i])?"***":word[i];
    }
    return finalword;
}
console.log(Word2('靠乾靠靠今天靠運氣超差,乾'));
</script>
6
froce
iT邦大師 1 級 ‧ 2021-01-14 01:02:41
const blacklist = ['靠','乾','他嗎的']
const pat = new RegExp(blacklist.join("|"), "gm")
'靠,今天運氣超差,乾'.replaceAll(pat, "***")

result: ",今天運氣超差,"

補ie11作法,更早之前我就不想花時間了。

var blacklist = ['靠','乾','他嗎的']
var pat = new RegExp(blacklist.join("|"), "gm")
'靠,今天運氣超差,乾'.replace(pat, "***")

我要發表回答

立即登入回答