场景:
业务系统不能出现敏感词或辱骂言论...
解决方法:
通过百度一下,查到DFA是唯一比较契合及友好的实现算法。DFA即Deterministic Finite Automaton,也就是确定有穷自动机,它是是通过event和当前的state得到下一个state,即event+state=nextstate。
实现方式:
我们这里使用的是将敏感词汇集合在文件里,放入服务器,服务启动后将文件内容加载进缓存中,方便比较敏感词直接取及动态配置。
//将敏感词字典加入缓存
public static List<String> loadKeywords() {
System.out.println("将敏感词字典加入缓存");
List<String> keyArray = new ArrayList<String>();
try {
URL url = new URL("xxxx.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream(),"UTF-8"));
// 构造一个BufferedReader类来读取文件
String s = null;
while ((s = br.readLine()) != null) {
// 使用readLine方法,一次读一行
keyArray.add(s);
}
br.close();
} catch (Exception e) {
logger.error("将敏感词字典加入缓存失败",e);
}
return keyArray;
}
//方法使用 这里是提前设置敏感词字典
IllegalWordsSearch illegalWordsSearch = new IllegalWordsSearch();
String s = redisTemplate.opsForValue().get(RedisKeyConstant.ILLEGAL_WORDS_CACHE);
if (StringUtils.isNotEmpty(s)){
List<String> list = JSON.parseArray(s, String.class);
illegalWordsSearch.SetKeywords(list);
}else {
List<String> list = IllegalWordsSearch.loadKeywords();
illegalWordsSearch.SetKeywords(list);
}
//校验敏感词
IllegalWordsSearchResult illegalWordsSearchResult = illegalWordsSearch.FindFirst(tradeSettlementOrderDO.getMerchantRemark());
if(null != illegalWordsSearchResult){
String string = new StringBuilder().append("备注存在敏感词-\"").append(illegalWordsSearchResult.MatchKeyword).append("\"").toString();
logger.error(string);
}
public class IllegalWordsSearchResult
{
public IllegalWordsSearchResult(final String keyword, final int start, final int end, final int index,
final String matchKeyword, final int type)
{
MatchKeyword = matchKeyword;
End = end;
Start = start;
Index = index;
Keyword = keyword;
BlacklistType = type;
}
/**开始位置 */
public int Start;
/**结束位置 */
public int End ;
/**原始文本 */
public String Keyword ;
/**关键字 */
public String MatchKeyword;
/**黑名单类型 */
public int BlacklistType ;
/**索引 */
public int Index;
}
参考文献:https://github.com/toolgood/ToolGood.Words
https://www.cnblogs.com/toolgood/p/15208734.html