開源了一個 JavaScript 版敏感詞過濾庫

老錢發表於2019-03-04

最近在做一個專案,尋遍了 Node 開源社群居然沒有發現一個好用的敏感詞過濾庫,有那麼幾個庫外觀上看起來似乎還不錯,用起來卻一塌糊塗,震驚有餘,失望至極。於是花了一天時間自己擼了一個庫,庫名叫 fastscan,這是我的第一個 Node 開源專案,它也可以用於瀏覽器環境。fastscan 基於廣為人知的 ahocorasick 高效能字串匹配演算法。

專案地址:github.com/pyloque/fas…

演示地址:pyloque.github.com/fastscan

開源了一個 JavaScript 版敏感詞過濾庫

考慮到太多的違禁詞彙,所以縮小化顯示,縮小到讓你看不清楚。如果想看清楚一點,還是去演示地址裡面看吧。消滅敏感詞是每個公民義不容辭的責任!你不站崗我不站崗,誰保衛我們祖國誰來保衛家!讀者們你們要是敢舉報,看我不砍死你!

安裝方法

# 安裝到當前專案
npm install --save fastscan
# 寫了不少單元測試,感興趣執行一下
npm test
複製程式碼

使用方法

import FastScanner from fastscan

var words = ["今日頭條""微信", "支付寶"]
var scanner = new FastScanner(words)
var content = "今日頭條小程式終於來了,這是繼微信、支付寶、百度後,第四個推出小程式功能的App。貓眼電影率先試水,出現在今日頭條。"
var offWords = scanner.search(content)
console.log(offWords)
var hits = scanner.hits(content)
console.log(hits)

-------------
[ [ 0, '今日頭條' ], [ 15, '微信' ], [ 18, '支付寶' ], [ 53, '今日頭條' ] ]
{ '今日頭條': 2, '微信': 1, '支付寶': 1 }
複製程式碼

API

  1. 查詢匹配的詞彙以及所在字串的位置 search(content, option={})
  2. 查詢匹配詞彙的命中數量 hits(content, options={})
  3. 臨時動態增加詞彙,不修正其它詞彙的回溯指標 add(word)
options = {quick: false, longest: false}
複製程式碼
  1. quick 選項表示快速模式,匹配到一個就立即返回
  2. longest 表示最長模式,同一個位置出現多個詞彙(中國、中國人),選擇最長的一個(中國人)
  3. 預設匹配出所有的詞彙,同一個位置可能會出現多個詞彙

效能

專案程式碼使用原生的 js 實現,我開始非常擔心詞彙樹的構建速度會不會太慢。經測試後發現雖然效能不算太快,不過也不是太差,對於絕大多數專案來說已經綽綽有餘了。我分別測試了構造 20000~100000 個詞彙的樹結構,每個詞彙隨機在 10~20之間,耗時情況如下

20000 words 385ms
40000 words 654ms
60000 words 1108ms
80000 words 1273ms
100000 words 1659ms

如果你的詞彙比較短小,構建樹的速度還會更快。

查詢效能我並不擔心,因為 ahocorasick 演算法在詞彙長度較短的情況下複雜度是 O(n),效能和被過濾內容的長度乘線性變化。下面我使用 100000 詞彙量構建的樹分別對 20000 ~ 100000字的內容進行了過濾,耗時情況如下

20000 words 12ms
40000 words 28ms
60000 words 35ms
80000 words 49ms
100000 words 51ms

fastscan 可以做到以迅雷不及掩耳的速度掃遍一幅 10w 字的長文,10w 大概就是一部中篇小說的長度了。如果你要掃百萬字的長篇小說,那還是建議你分章分節來掃吧。

記憶體佔用也是需要考慮的點,記憶體對於 Node 程式來說本來就非常有限,如果因為敏感詞樹佔據了太大的記憶體那是非常要不得的大問題。所以我也對記憶體佔用進行了測試,下面是測試的結果

0 words 14M
20000 words 81M
40000 words 135M
60000 words 184M
80000 words 234M
100000 words 277M

詞彙量不是太大的話,這樣的記憶體佔用還是可以接受的。如果你對記憶體佔用不滿意,那就只能使用 Node 的 C 語言擴充套件來打造更高效能的庫了,考慮到成本問題,恕我目前無能為力。

注:不得不說,node 社群釋出開源類庫太方便了,npm login && npm publish 輕鬆搞定。個人覺得這大概就是 node 輪子多的罪魁禍首。對比之前釋出 java 社群開源專案,感覺自己頭髮都快掉光了,造輪子比釋出輪子還要輕鬆。

圖片

如果讀者比較關心演算法的原理和細節,請關注我的公眾號「碼洞」,後續我會編寫相關文章來仔細講解演算法的原理,以及對 fastscan 專案程式碼的剖析。

相關文章