最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實現(xiàn)一個敏感詞過濾有哪些方法以及怎么優(yōu)化詳解

 更新時間:2025年07月17日 09:55:19   作者:尤物程序猿  
我們在開發(fā)系統(tǒng)或者應(yīng)用的過程中,經(jīng)常需要對用戶提交的評論或者文章進(jìn)行審核,對其中的敏感詞進(jìn)行校驗或者過濾,這篇文章主要介紹了Java實現(xiàn)一個敏感詞過濾有哪些方法以及怎么優(yōu)化的相關(guān)資料,需要的朋友可以參考下

敏感詞過濾是非常常見的一種手段,避免出現(xiàn)一些違規(guī)詞匯。

Java實現(xiàn)敏感詞過濾的完整方案與優(yōu)化策略

敏感詞過濾是內(nèi)容安全的重要組成部分,以下是Java中實現(xiàn)敏感詞過濾的多種方法及其優(yōu)化方案。

一、基礎(chǔ)實現(xiàn)方法

1. 簡單字符串匹配(適合小規(guī)模場景)

public class SimpleFilter {
    private static final Set<String> sensitiveWords = new HashSet<>(Arrays.asList("敏感詞1", "敏感詞2"));
    
    public static String filter(String text) {
        for (String word : sensitiveWords) {
            if (text.contains(word)) {
                text = text.replace(word, "***");
            }
        }
        return text;
    }
}

缺點(diǎn):時間復(fù)雜度O(n*m),性能差,無法處理變形詞,拼音等擴(kuò)展功能。

2. 正則表達(dá)式匹配

public class RegexFilter {
    private static final String pattern = "敏感詞1|敏感詞2|敏感詞3";
    
    public static String filter(String text) {
        return text.replaceAll(pattern, "***");
    }
}

缺點(diǎn):正則構(gòu)建時間長,敏感詞多時性能下降明顯。敏感詞有些場景還是可以考慮的,可以做一個分片處理。

二、高效實現(xiàn)方案

1. Trie樹(前綴樹)實現(xiàn)

class TrieNode {
    private Map<Character, TrieNode> children = new HashMap<>();
    private boolean isEnd;
    
    // 添加子節(jié)點(diǎn)方法
    // 查找子節(jié)點(diǎn)方法
    // getter/setter
}

public class TrieFilter {
    private TrieNode root = new TrieNode();
    
    // 構(gòu)建Trie樹
    public void addWord(String word) {
        TrieNode node = root;
        for (char c : word.toCharArray()) {
            node = node.getChildren().computeIfAbsent(c, k -> new TrieNode());
        }
        node.setEnd(true);
    }
    
    // 過濾方法
    public String filter(String text) {
        StringBuilder result = new StringBuilder();
        TrieNode temp;
        for (int i = 0; i < text.length(); i++) {
            temp = root;
            int j = i;
            while (j < text.length() && temp.getChildren().containsKey(text.charAt(j))) {
                temp = temp.getChildren().get(text.charAt(j));
                j++;
                if (temp.isEnd()) {
                    // 發(fā)現(xiàn)敏感詞,替換為*
                    result.append("*".repeat(j - i));
                    i = j - 1;
                    break;
                }
            }
            if (i >= text.length()) break;
            if (!temp.isEnd()) {
                result.append(text.charAt(i));
            }
        }
        return result.toString();
    }
}

其實也就是一種樹形有向圖(無環(huán)結(jié)構(gòu)。是DFA的一種特例(樹形結(jié)構(gòu),無失敗轉(zhuǎn)移)。

優(yōu)點(diǎn):時間復(fù)雜度O(n),適合大規(guī)模敏感詞庫

前綴樹的優(yōu)點(diǎn)是,插入和查詢效率高,特別是在敏感詞有共同前綴的情況下(如ab、abc、abcd)。而且他的空間效率較高,因為是共享公共前綴的。

但是他也有缺點(diǎn),一方面是構(gòu)建樹的初期成本較高。另外對于沒有共同前綴的敏感詞,效率提升不明顯。

所以,前綴樹適合做高效的字典查找、根據(jù)前綴自動補(bǔ)全、利用前綴匹配進(jìn)行快速路由等場景。

2. DFA(確定性有限自動機(jī))算法

DFA是Deterministic Finite Automaton的縮寫,翻譯過來叫確定有限自動機(jī),DFA算法是一種高效的文本匹配算法,特別適合于敏感詞過濾。

DFA由一組狀態(tài)組成,以及在這些狀態(tài)之間的轉(zhuǎn)換,這些轉(zhuǎn)換由輸入字符串驅(qū)動。每個狀態(tài)都知道下一個字符的到來應(yīng)該轉(zhuǎn)移到哪個狀態(tài)。如果輸入字符串結(jié)束時,DFA處于接受狀態(tài),則輸入字符串被認(rèn)為是匹配的。

其實就是一種一般有向圖(可能含環(huán),如自環(huán))結(jié)構(gòu),滿足一條路徑則算匹配成功,就算一個敏感詞了。

有三個參數(shù)組成

  1. 節(jié)點(diǎn)(States):表示自動機(jī)的狀態(tài),包括:

    • 初始狀態(tài)(起點(diǎn))

    • 中間狀態(tài)

    • 終止?fàn)顟B(tài)(敏感詞匹配成功的狀態(tài))

  2. 邊(Transitions):表示狀態(tài)之間的轉(zhuǎn)移條件,每個邊對應(yīng)一個輸入字符(如字母、漢字)。

  3. 終止?fàn)顟B(tài):某些節(jié)點(diǎn)被標(biāo)記為終止?fàn)顟B(tài),代表從初始狀態(tài)到該狀態(tài)的路徑對應(yīng)一個完整的敏感詞。

具體過程就像下面這樣

  • 輸入字符 c,檢查當(dāng)前狀態(tài)是否有 c 對應(yīng)的邊。

  • 如果有,轉(zhuǎn)移到下一個狀態(tài);如果沒有,匹配失敗。

  • 如果最終停在終止?fàn)顟B(tài),則輸入文本包含敏感詞。

  • 否則,不包含。

public class DFAFilter {
    private Map<String, Object> sensitiveWordMap = new HashMap<>();
    
    // 構(gòu)建敏感詞庫
    public void init(Set<String> words) {
        for (String word : words) {
            Map<String, Object> nowMap = sensitiveWordMap;
            for (int i = 0; i < word.length(); i++) {
                String key = String.valueOf(word.charAt(i));
                Object tempMap = nowMap.get(key);
                if (tempMap == null) {
                    Map<String, Object> newMap = new HashMap<>();
                    newMap.put("isEnd", "0");
                    nowMap.put(key, newMap);
                    nowMap = newMap;
                } else {
                    nowMap = (Map<String, Object>) tempMap;
                }
                if (i == word.length() - 1) {
                    nowMap.put("isEnd", "1");
                }
            }
        }
    }
    
    // 過濾方法
    public String filter(String text) {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < text.length(); i++) {
            int length = checkWord(text, i);
            if (length > 0) {
                result.append("*".repeat(length));
                i += length - 1;
            } else {
                result.append(text.charAt(i));
            }
        }
        return result.toString();
    }
    
    private int checkWord(String text, int beginIndex) {
        boolean flag = false;
        int matchLength = 0;
        Map<String, Object> tempMap = sensitiveWordMap;
        for (int i = beginIndex; i < text.length(); i++) {
            String word = String.valueOf(text.charAt(i));
            tempMap = (Map<String, Object>) tempMap.get(word);
            if (tempMap == null) break;
            matchLength++;
            if ("1".equals(tempMap.get("isEnd"))) {
                flag = true;
                break;
            }
        }
        return flag ? matchLength : 0;
    }
}
  1. 內(nèi)存優(yōu)化

    • 雙數(shù)組Trie:壓縮狀態(tài)存儲,減少內(nèi)存占用。

    • 共享前綴:DFA合并相同前綴的狀態(tài)(如 "敏感詞" 和 "敏感內(nèi)容" 共享 "敏感" 路徑)。

  2. 匹配加速

    • AC自動機(jī)在DFA基礎(chǔ)上添加失敗指針,支持多模式匹配(類似KMP算法)。

    • 批處理:對長文本分塊并行檢測。

  3. 工程實踐

    • 熱更新:動態(tài)加載敏感詞庫,無需重啟服務(wù)。

    • 多級過濾:先布隆過濾器快速排除無敏感詞文本,再走DFA精確匹配。

給大家推薦一個基于 DFA 算法實現(xiàn)的高性能 java 敏感詞過濾工具框架——sensitive-word

三、高級優(yōu)化方案

1. 多模式匹配算法優(yōu)化

AC自動機(jī)(Aho-Corasick算法)

public class ACFilter {
    private ACTrie trie;
    
    public void init(Set<String> words) {
        trie = new ACTrie();
        for (String word : words) {
            trie.insert(word);
        }
        trie.buildFailureLinks();
    }
    
    public String filter(String text) {
        Set<ACTrie.Match> matches = trie.parseText(text);
        char[] chars = text.toCharArray();
        for (ACTrie.Match match : matches) {
            Arrays.fill(chars, match.getStart(), match.getEnd() + 1, '*');
        }
        return new String(chars);
    }
}

優(yōu)點(diǎn):一次掃描匹配所有模式串,時間復(fù)雜度O(n)

2. 基于布隆過濾器的預(yù)處理

public class BloomFilterPreprocessor {
    private BloomFilter<String> bloomFilter;
    private Set<String> exactMatchSet;
    
    public void init(Set<String> words) {
        bloomFilter = BloomFilter.create(Funnels.stringFunnel(), words.size(), 0.01);
        exactMatchSet = new HashSet<>(words);
        words.forEach(bloomFilter::put);
    }
    
    public boolean mightContain(String text) {
        return bloomFilter.mightContain(text);
    }
    
    public boolean exactMatch(String text) {
        return exactMatchSet.contains(text);
    }
}

用途:先快速判斷是否可能包含敏感詞,再進(jìn)行精確匹配

四、工程化實踐方案

1. 敏感詞庫動態(tài)加載

public class DynamicWordFilter {
    private volatile Map<String, Object> wordMap;
    private ScheduledExecutorService executor;
    
    public void init() {
        loadWords();
        executor = Executors.newSingleThreadScheduledExecutor();
        executor.scheduleAtFixedRate(this::loadWords, 1, 1, TimeUnit.HOURS);
    }
    
    private void loadWords() {
        Map<String, Object> newMap = new HashMap<>();
        // 從數(shù)據(jù)庫或文件加載敏感詞
        Set<String> words = loadFromDB();
        // 構(gòu)建DFA結(jié)構(gòu)
        this.wordMap = buildDFA(words);
    }
}

2. 分布式敏感詞過濾

public class DistributedFilter {
    private RedisTemplate<String, String> redisTemplate;
    
    public boolean isSensitive(String text) {
        // 使用Redis的Set結(jié)構(gòu)存儲敏感詞
        return redisTemplate.opsForSet().isMember("sensitive:words", text);
    }
    
    public String filter(String text) {
        // 調(diào)用分布式過濾服務(wù)
        return restTemplate.postForObject("http://filter-service/filter", text, String.class);
    }
}

3:也可以考慮使用ElasticSearch做搜索引擎

為什么可以使用ES可以看看

為什么用ElasticSearch?和傳統(tǒng)數(shù)據(jù)庫MySQL與什么區(qū)別?

總的來說就是ES有強(qiáng)大的文本分析查詢能力來實現(xiàn)。以下是詳細(xì)實現(xiàn)過程和方案:

具體實現(xiàn)方案

方案1:索引時敏感詞標(biāo)記(推薦)

步驟

  1. 自定義分析器

    PUT /sensitive_content_index
    {
      "settings": {
        "analysis": {
          "analyzer": {
            "sensitive_filter_analyzer": {
              "type": "custom",
              "tokenizer": "standard",
              "filter": [
                "lowercase",
                "sensitive_word_filter"
              ]
            }
          },
          "filter": {
            "sensitive_word_filter": {
              "type": "stop",
              "stopwords": ["敏感詞1", "敏感詞2", "違法詞"]
            }
          }
        }
      },
      "mappings": {
        "properties": {
          "content": {
            "type": "text",
            "analyzer": "sensitive_filter_analyzer",
            "fields": {
              "original": { 
                "type": "keyword" // 保留原始內(nèi)容
              }
            }
          }
        }
      }
    }
  2. 檢測敏感詞

    GET /sensitive_content_index/_analyze
    {
      "analyzer": "sensitive_filter_analyzer",
      "text": "這是一段包含敏感詞1的文本"
    }
  3. 輸出:敏感詞會被過濾掉,只返回普通詞項

  4. 寫入時自動標(biāo)記

    POST /sensitive_content_index/_doc
    {
      "content": "這是需要檢測的文本",
      "has_sensitive": false // 由pipeline更新
    }
  5. 使用Ingest Pipeline自動檢測

    PUT _ingest/pipeline/sensitive_check_pipeline
    {
      "processors": [
        {
          "script": {
            "source": """
              def sensitiveWords = ['敏感詞1', '違禁詞'];
              for (word in sensitiveWords) {
                if (ctx.content.contains(word)) {
                  ctx.has_sensitive = true;
                  ctx.sensitive_word = word;
                  break;
                }
              }
            """
          }
        }
      ]
    }

方案2:查詢時敏感詞過濾

使用Term查詢檢測

GET /content_index/_search
{
  "query": {
    "bool": {
      "must_not": [
        { "terms": { "content": ["敏感詞1", "違禁詞"] }}
      ]
    }
  }
}

高亮顯示敏感詞

GET /content_index/_search
{
  "query": {
    "match": { "content": "正常文本" }
  },
  "highlight": {
    "fields": {
      "content": {
        "highlight_query": {
          "terms": { "content": ["敏感詞1", "違禁詞"] }
        }
      }
    }
  }
}

方案3:結(jié)合機(jī)器學(xué)習(xí)(ES 7.15+)

  1. 訓(xùn)練敏感詞分類模型

    PUT _ml/trained_models/sensitive_words_classifier
    {
      "input": {"field_names": ["text"]},
      "inference_config": {
        "text_classification": {
          "vocabulary": ["敏感詞1", "變體詞", "拼音詞"]
        }
      }
    }
  2. 部署推理處理器

    PUT _ingest/pipeline/ml_sensitive_detection
    {
      "processors": [
        {
          "inference": {
            "model_id": "sensitive_words_classifier",
            "field_map": { "content": "text" }
          }
        }
      ]
    }

性能優(yōu)化技巧

  1. 敏感詞庫存儲優(yōu)化

    • 使用ES的Synonyms Token Filter管理同義詞/變體詞

    • 將敏感詞庫存儲在單獨(dú)索引中,定期更新

  2. 緩存加速

    PUT /sensitive_words_cache
    {
      "mappings": {
        "properties": {
          "word": { "type": "keyword" }
        }
      }
    }
  3. 分布式檢測

    • 對大型文檔分片處理

    • 使用_search_shardsAPI并行檢測

五、性能優(yōu)化技巧

  1. 內(nèi)存優(yōu)化

    • 使用基本類型替代包裝類

    • 壓縮Trie樹結(jié)構(gòu)(Ternary Search Tree)

    • 對象復(fù)用減少GC壓力

  2. 算法優(yōu)化

    • 對短文本使用快速失敗策略

    • 實現(xiàn)多級過濾(先粗篩后精篩),

    • 并行化處理(Fork/Join框架)

  3. 預(yù)處理優(yōu)化

    • 文本歸一化(全角轉(zhuǎn)半角,繁體轉(zhuǎn)簡體)

    • 拼音轉(zhuǎn)換處理(如"taobao"->"淘寶")

    • 近音詞/形近詞處理

  4. 緩存優(yōu)化

    • 緩存常見文本的過濾結(jié)果

    • 使用Caffeine實現(xiàn)本地緩存

    • 布隆過濾器預(yù)判

六、完整生產(chǎn)級實現(xiàn)示例

public class ProductionWordFilter implements InitializingBean {
    private final TrieNode root = new TrieNode();
    private final List<String> wordSources;
    private final ScheduledExecutorService executor;
    
    public ProductionWordFilter(List<String> wordSources) {
        this.wordSources = wordSources;
        this.executor = Executors.newSingleThreadScheduledExecutor();
    }
    
    @Override
    public void afterPropertiesSet() {
        reload();
        executor.scheduleWithFixedDelay(this::reload, 1, 1, TimeUnit.HOURS);
    }
    
    public synchronized void reload() {
        TrieNode newRoot = new TrieNode();
        wordSources.stream()
                  .flatMap(source -> loadWords(source).stream())
                  .forEach(word -> addWord(newRoot, word));
        this.root = newRoot;
    }
    
    public FilterResult filter(String text) {
        StringBuilder result = new StringBuilder();
        Set<String> foundWords = new HashSet<>();
        int replacedCount = 0;
        
        for (int i = 0; i < text.length(); ) {
            MatchResult match = findNextMatch(text, i);
            if (match != null) {
                foundWords.add(match.getWord());
                result.append("*".repeat(match.getLength()));
                replacedCount++;
                i = match.getEndIndex();
            } else {
                result.append(text.charAt(i));
                i++;
            }
        }
        
        return new FilterResult(result.toString(), foundWords, replacedCount);
    }
    
    // 其他輔助方法...
}

七、評估指標(biāo)

  1. 性能指標(biāo)

    • 吞吐量(QPS)

    • 平均延遲(ms)

    • 99線延遲(ms)

  2. 效果指標(biāo)

    • 召回率(漏判率)

    • 準(zhǔn)確率(誤判率)

    • 覆蓋度(變形詞識別率)

  3. 資源消耗

    • 內(nèi)存占用

    • CPU使用率

    • 網(wǎng)絡(luò)IO(分布式場景)

八、擴(kuò)展思考

  1. 中文分詞集成:結(jié)合IK Analyzer等分詞工具處理更復(fù)雜的語義

  2. 機(jī)器學(xué)習(xí)模型:使用NLP模型識別變體、諧音、拆字等高級變種

  3. 圖片/語音過濾:擴(kuò)展多媒體內(nèi)容過濾能力

  4. 多語言支持:處理Unicode混淆和國際化敏感詞

對于大多數(shù)Java應(yīng)用,Trie樹或DFA算法配合定期更新的詞庫已經(jīng)能夠滿足需求。

總結(jié)

到此這篇關(guān)于Java實現(xiàn)一個敏感詞過濾有哪些方法以及怎么優(yōu)化的文章就介紹到這了,更多相關(guān)Java實現(xiàn)敏感詞過濾內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中的JVM虛擬機(jī)內(nèi)存分配詳解

    Java中的JVM虛擬機(jī)內(nèi)存分配詳解

    這篇文章主要介紹了Java中的JVM虛擬機(jī)內(nèi)存分配詳解,虛擬機(jī)是一種能夠執(zhí)行 Java 字節(jié)碼的虛擬機(jī),它是 Java 語言的核心組成部分,負(fù)責(zé)將 Java 代碼轉(zhuǎn)換為機(jī)器碼并執(zhí)行,JVM 提供了內(nèi)存管理、垃圾回收、線程管理等功能,需要的朋友可以參考下
    2023-10-10
  • JavaEE中關(guān)于ServletConfig的小結(jié)

    JavaEE中關(guān)于ServletConfig的小結(jié)

    ServletConfig是針對特定的Servlet的參數(shù)或?qū)傩浴ervletConfig是表示單獨(dú)的Servlet的配置和參數(shù),只是適用于特定的Servlet。從一個servlet被實例化后,對任何客戶端在任何時候訪問有效,但僅對本servlet有效,一個servlet的ServletConfig對象不能被另一個servlet訪問
    2014-10-10
  • java開發(fā)AOP面向切面編程入門

    java開發(fā)AOP面向切面編程入門

    這篇文章主要介紹了java開發(fā)的AOP面向切面編程入門的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步學(xué)有所得
    2021-10-10
  • Java圖片處理之獲取gif圖一幀圖片的兩種方法

    Java圖片處理之獲取gif圖一幀圖片的兩種方法

    這篇文章主要給大家介紹了關(guān)于Java圖片處理之獲取gif圖一幀圖片的兩種方法,分別是利用Java原生代碼和使用im4java調(diào)用ImageMagick來實現(xiàn),兩種方法都給出來示例代碼供大家參考學(xué)習(xí),需要的朋友們下面來一起看看吧。
    2017-10-10
  • Java簡單實現(xiàn)session保存到redis的方法示例

    Java簡單實現(xiàn)session保存到redis的方法示例

    這篇文章主要介紹了Java簡單實現(xiàn)session保存到redis的方法,結(jié)合實例形式分析了Java將session存入redis緩存服務(wù)器的相關(guān)設(shè)置、實現(xiàn)技巧與操作注意事項,需要的朋友可以參考下
    2018-05-05
  • SpringSecurity在分布式環(huán)境下的使用流程分析

    SpringSecurity在分布式環(huán)境下的使用流程分析

    文章介紹了Spring?Security在分布式環(huán)境下的使用,包括單點(diǎn)登錄(SSO)的概念、流程圖以及JWT(JSON?Web?Token)的生成和校驗,通過使用JWT和RSA非對稱加密,可以實現(xiàn)安全的分布式認(rèn)證,感興趣的朋友一起看看吧
    2025-02-02
  • 關(guān)于JSqlparser使用攻略(高效的SQL解析工具)

    關(guān)于JSqlparser使用攻略(高效的SQL解析工具)

    這篇文章主要介紹了關(guān)于JSqlparser使用攻略(高效的SQL解析工具),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • java.io.UncheckedIOException: Cannot delete C:\Users\guo\AppData\Local\Temp\tomcat.8081問題

    java.io.UncheckedIOException: Cannot delete C

    本文主要介紹了java.io.UncheckedIOException: Cannot delete C:\Users\guo\AppData\Local\Temp\tomcat.8081問題,具有一定的參考價值,感興趣的可以了解一下
    2024-05-05
  • SpringBoot整合Druid實現(xiàn)SQL監(jiān)控和數(shù)據(jù)庫密碼加密

    SpringBoot整合Druid實現(xiàn)SQL監(jiān)控和數(shù)據(jù)庫密碼加密

    Druid連接池是阿里巴巴開源的數(shù)據(jù)庫連接池項目,Druid連接池為監(jiān)控而生,內(nèi)置強(qiáng)大的監(jiān)控功能,監(jiān)控特性不影響性能,本文給大家介紹了SpringBoot整合Druid實現(xiàn)SQL監(jiān)控和數(shù)據(jù)庫密碼加密,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下
    2024-06-06
  • SpringBoot http請求注解@RestController原理解析

    SpringBoot http請求注解@RestController原理解析

    這篇文章主要介紹了SpringBoot http請求注解@RestController原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01

最新評論

曲水县| 泸溪县| 贵德县| 安吉县| 儋州市| 晋江市| 岢岚县| 八宿县| 岢岚县| 元阳县| 宁德市| 南涧| 大埔区| 遵义市| 敖汉旗| 酒泉市| 牙克石市| 湘潭县| 湘乡市| 清镇市| 五台县| 临清市| 子洲县| 板桥市| 涿州市| 南平市| 麻阳| 梧州市| 永宁县| 青铜峡市| 拜城县| 盱眙县| 遂平县| 阳信县| 富蕴县| 调兵山市| 平度市| 周至县| 南投市| 承德县| 玉田县|