Android離線敏感詞校驗

本文資源來自:https://github.com/k5h9999/keywordfilter
作者: k5h9999
說明:基于分詞原理修改寫的一個過濾敏感詞庫忆家,可以改成動態(tài)闻蛀,本敏感詞收集了4W多個違法詞押搪、敏感詞港华、違禁詞鱼冀,幾十個矯正詞累铅、變異詞糕非。

最近做Android項目用到敏感詞校驗功能蒙具,原本想到用在線檢測功能,不過太依賴于網(wǎng)絡(luò)朽肥,而且校驗服務(wù)器也不一定能一直開通禁筏,于是想到了找一下離線庫。

文章開頭的鏈接是作者為Java寫的代碼衡招,我稍加修改篱昔,將其用到了我的Android項目中。感謝原作者的分享蚁吝。
下面是步驟:

1.將詞庫放到項目中

將上述項目文件src\main\resources\META-INF\dic目錄中的兩個文件:fqc.dicwfc.dic解壓縮旱爆,放到Android項目的assets資源文件夾中。如果Android項目中沒有這個文件夾窘茁,在main目錄下自己新建即可怀伦。

2.修改代碼適配Android

作者的原項目中只有兩個類,WordFilterKeyWordFilter山林,其中在WordFilter類中持有對KeyWordFilter的引用房待。
我們打開KeyWordFilter邢羔,找到main方法,查看用法桑孩,發(fā)現(xiàn)里面有這樣的代碼:

public static void main(String[] args) {
    String str = "一個網(wǎng)站就像一個人拜鹤,存在一個從小到大白粉的過程。養(yǎng)一個網(wǎng)站和養(yǎng)一個人一樣流椒,不同時期漂白粉需要不同的方法敏簿,口交--不同的方法下有共24口交換機同的原則。";
    Long startTime = System.currentTimeMillis();
    WordFilter wf = new WordFilter();
    //WordFilter.filter_search(String) 方法是從字符串中刪除敏感詞后返回結(jié)果
    System.out.println(wf.filter_search(str));
    //WordFilter.filter_jk_info(String)方法是將敏感詞標(biāo)記出來
    System.out.println(wf.filter_jk_info("一個網(wǎng)站就像一個人"));
    Long endTime = System.currentTimeMillis();
    System.out.println("時間:" + (endTime - startTime));
}

我們找到filter_jk_info方法宣虾,查看其實現(xiàn):

public String filter_jk_info(String content){
    return kwf.filter_jk(content,"0","0","<font color=#ff0000>","</font>","<font color=#00ff00>","</font>");
}

再轉(zhuǎn)到filter_jk方法惯裕,發(fā)現(xiàn)這里就是核心算法。對比結(jié)果發(fā)現(xiàn)绣硝,此方法是將敏感詞用html標(biāo)簽標(biāo)記為紅色和綠色蜻势。
我們直接嘗試調(diào)用會報空指針異常。跟隨異常信息鹉胖,發(fā)現(xiàn)原來是讀取詞庫的時候握玛,數(shù)據(jù)流報空指針錯誤:
KeyWordFilter.java

private HashMap<String, String> getWordMap(String dicPath, String replace) {
    InputStream is = null;
    HashMap<String, String> wordMap = new HashMap<String, String>();
    try {
        //就是下面這一行返回的is為空
        is = KeyWordFilter.class.getResourceAsStream(dicPath);       
        if (is == null) {
            System.out.println(dicPath + " not found!!!");
        }
        BufferedReader br = new BufferedReader(new InputStreamReader(is,
                "UTF-8"), 512);
        String theWord = null;
        //
        //    省略部分代碼
        //
}

首先將詞庫文件的全局變量路徑修改為:

public static final String PATH_DIC_WFC = "wfc.dic";
public static final String PATH_DIC_FQC = "fqc.dic";

然后將空指針那一行代碼改成:

is = App.getContext().getResources().getAssets().open(dicPath);

其中App.getContext()是自定義Application中的方法,自己添加即可甫菠。
這樣就獲取到了assets目錄下的文件挠铲,并返回了InputStream

最后寂诱,就可以調(diào)用了市殷。

WordFilter mKeywordFilter = new WordFilter();
String s = mKeywordFilter.filter_jk_info2(content);

filter_jk_info2方法的返回值為:

  • 如果沒有敏感詞,返回原文刹衫;
  • 如果有敏感詞,返回將敏感詞標(biāo)記后的字符串搞挣,標(biāo)記規(guī)則在KeyWordFilter.filter_jk方法中带迟。
    所以,我們可以修改filter_jk_info方法如下:
public String filter_jk_info(String content) {
    return kwf.filter_jk(content, "0", "0", "<mgc>", "</mgc>", "<mgc>", "</mgc>");
    }

然后判斷返回值s是否包含<mgc>標(biāo)簽即可囱桨。

總結(jié)修改

WordFilter.java

public String filter_jk_info2(String content) {
    return kwf.filter_jk(content, "0", "0", "<mgc>", "</mgc>", "<mgc>", "</mgc>");
    }

KeyWordFilter.java

public static final String PATH_DIC_WFC = "wfc.dic";
public static final String PATH_DIC_FQC = "fqc.dic";

private HashMap<String, String> getWordMap(String dicPath, String replace) {
    InputStream is = null;
    HashMap<String, String> wordMap = new HashMap<String, String>();
    try {
        is = App.getContext().getResources().getAssets().open(dicPath);
        if (is == null) {
            System.out.println(dicPath + " not found!!!");
        }
        BufferedReader br = new BufferedReader(new InputStreamReader(is,
                "UTF-8"), 512);
        String theWord = null;
        //
        //    省略部分代碼
        //
}

使用:

private WordFilter mKeywordFilter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    // 省略部分代碼
    mKeywordFilter = new WordFilter();
    //因為內(nèi)部是靜態(tài)對象仓犬,所以這里先調(diào)用一次生成實例,后面可以加速查找過程舍肠,懶得改源碼了
    new Thread(() -> mKeywordFilter.filter_jk_info2("初始化")).start();
}
public void checkContent(){
    String s = mKeywordFilter.filter_jk_info("測試內(nèi)容");
    if(s.contains("<mgc>") || s.contains("</mgc>")){
        //包含敏感詞的操作
    }    
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末搀继,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子翠语,更是在濱河造成了極大的恐慌叽躯,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肌括,死亡現(xiàn)場離奇詭異点骑,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門黑滴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來憨募,“玉大人,你說我怎么就攤上這事袁辈〔艘ィ” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵晚缩,是天一觀的道長尾膊。 經(jīng)常有香客問我,道長橡羞,這世上最難降的妖魔是什么眯停? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮卿泽,結(jié)果婚禮上莺债,老公的妹妹穿的比我還像新娘。我一直安慰自己签夭,他們只是感情好齐邦,可當(dāng)我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著第租,像睡著了一般措拇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上慎宾,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天丐吓,我揣著相機與錄音,去河邊找鬼趟据。 笑死券犁,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的汹碱。 我是一名探鬼主播粘衬,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼咳促!你這毒婦竟也來了稚新?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤跪腹,失蹤者是張志新(化名)和其女友劉穎褂删,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體尺迂,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡笤妙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年冒掌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹲盘。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡股毫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出召衔,到底是詐尸還是另有隱情铃诬,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布苍凛,位于F島的核電站趣席,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏醇蝴。R本人自食惡果不足惜宣肚,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望悠栓。 院中可真熱鬧霉涨,春花似錦、人聲如沸惭适。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽癞志。三九已至往枷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間凄杯,已是汗流浹背错洁。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留戒突,地道東北人墓臭。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像妖谴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子酌摇,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,927評論 2 355