一、簡介
在文本處理中,常常需要在一段文本里查找多個關鍵字是否存在,例如敏感詞過濾、關鍵詞匹配等場景。Hutool - DFA 模塊基于確定性有限自動機(Deterministic Finite Automaton,DFA)模型,為我們提供了高效的多關鍵字查找功能。DFA 模型是一種狀態機,它通過預先構建一個狀態轉移表,能夠在一次遍歷文本的過程中,快速判斷是否存在多個關鍵字,時間復雜度為 O ( n ) O(n) O(n),其中 n n n 是文本的長度,這使得它在處理大規模文本和大量關鍵字時具有很高的效率。
二、引入依賴
若使用 Maven 項目,在 pom.xml
中添加以下依賴:
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version>
</dependency>
如果是 Gradle 項目,在 build.gradle
中添加:
implementation 'cn.hutool:hutool-all:5.8.16'
三、基本使用步驟
1. 創建 DFA 匹配器
import cn.hutool.dfa.FoundWord;
import cn.hutool.dfa.WordTree;
import java.util.ArrayList;
import java.util.List;public class DFAExample {public static void main(String[] args) {// 創建 WordTree 對象,用于構建 DFA 模型WordTree wordTree = new WordTree();// 添加關鍵字List<String> keywords = new ArrayList<>();keywords.add("蘋果");keywords.add("香蕉");keywords.add("葡萄");wordTree.addWords(keywords);}
}
在上述代碼中,首先創建了一個 WordTree
對象,它是 Hutool - DFA 中用于構建 DFA 模型的核心類。然后,創建一個包含多個關鍵字的列表,并使用 addWords
方法將這些關鍵字添加到 WordTree
中,從而完成 DFA 模型的構建。
2. 進行關鍵字查找
import cn.hutool.dfa.FoundWord;
import cn.hutool.dfa.WordTree;
import java.util.ArrayList;
import java.util.List;public class DFAExample {public static void main(String[] args) {// 創建 WordTree 對象,用于構建 DFA 模型WordTree wordTree = new WordTree();// 添加關鍵字List<String> keywords = new ArrayList<>();keywords.add("蘋果");keywords.add("香蕉");keywords.add("葡萄");wordTree.addWords(keywords);// 待查找的文本String text = "我喜歡吃蘋果和香蕉。";// 查找文本中包含的關鍵字List<FoundWord> foundWords = wordTree.matchAll(text);for (FoundWord foundWord : foundWords) {System.out.println("找到關鍵字:" + foundWord.getWord() + ",起始位置:" + foundWord.getStartIndex() + ",結束位置:" + foundWord.getEndIndex());}}
}
在這個代碼片段中,定義了一段待查找的文本,然后使用 matchAll
方法在文本中查找之前添加的關鍵字。matchAll
方法會返回一個 FoundWord
對象的列表,每個 FoundWord
對象包含了找到的關鍵字、關鍵字在文本中的起始位置和結束位置。通過遍歷這個列表,我們可以輸出找到的關鍵字及其位置信息。
四、高級用法
1. 忽略大小寫匹配
import cn.hutool.dfa.FoundWord;
import cn.hutool.dfa.WordTree;
import java.util.ArrayList;
import java.util.List;public class CaseInsensitiveDFAExample {public static void main(String[] args) {WordTree wordTree = new WordTree();List<String> keywords = new ArrayList<>();keywords.add("Apple");wordTree.addWords(keywords);String text = "I like apple.";// 忽略大小寫進行匹配List<FoundWord> foundWords = wordTree.matchAll(text, true);for (FoundWord foundWord : foundWords) {System.out.println("找到關鍵字:" + foundWord.getWord() + ",起始位置:" + foundWord.getStartIndex() + ",結束位置:" + foundWord.getEndIndex());}}
}
在 matchAll
方法中,第二個參數設置為 true
表示忽略大小寫進行匹配。這樣,即使文本中的關鍵字大小寫與添加的關鍵字不一致,也能被正確匹配。
2. 最長匹配原則
import cn.hutool.dfa.FoundWord;
import cn.hutool.dfa.WordTree;
import java.util.ArrayList;
import java.util.List;public class LongestMatchDFAExample {public static void main(String[] args) {WordTree wordTree = new WordTree();List<String> keywords = new ArrayList<>();keywords.add("蘋果");keywords.add("紅蘋果");wordTree.addWords(keywords);String text = "我喜歡吃紅蘋果。";// 開啟最長匹配List<FoundWord> foundWords = wordTree.matchAll(text, false, true);for (FoundWord foundWord : foundWords) {System.out.println("找到關鍵字:" + foundWord.getWord() + ",起始位置:" + foundWord.getStartIndex() + ",結束位置:" + foundWord.getEndIndex());}}
}
在 matchAll
方法中,第三個參數設置為 true
表示使用最長匹配原則。在上述示例中,文本中包含“紅蘋果”,由于開啟了最長匹配,只會匹配到“紅蘋果”,而不會匹配到“蘋果”。
五、注意事項
- 關鍵字添加順序:關鍵字的添加順序不影響匹配結果,因為 DFA 模型是基于狀態轉移的,所有關鍵字會被統一構建到狀態轉移表中。
- 性能考慮:DFA 模型在處理大規模文本和大量關鍵字時具有較高的性能,但在構建 DFA 模型時,需要消耗一定的內存和時間。因此,在實際應用中,應根據具體情況合理管理關鍵字的數量。
- 字符編碼:確保文本和關鍵字使用相同的字符編碼,避免因編碼問題導致匹配失敗。
通過使用 Hutool - DFA,開發者可以方便地實現高效的多關鍵字查找功能,無論是敏感詞過濾、信息檢索還是其他文本處理場景,都能輕松應對。