定义前缀树类
public class TrieNode {
private boolean end = false;
private Map<Character, TrieNode> subNodes = new HashMap<Character, TrieNode>();
public void addSubNode(Character key, TrieNode node) {
this.subNodes.put(key, node);
}
public TrieNode getSubNode(Character key) {
return this.subNodes.get(key);
}
public boolean isEnd() {
return end;
}
public void setEnd(boolean end) {
this.end = end;
}
}
敏感词过滤服务
@Service
public class SensitiveService implements InitializingBean {
private static final Logger logger = LoggerFactory.getLogger(SensitiveService.class);
private TrieNode rootNode = new TrieNode();
/**
* Spring在构建Bean时自动调用该方法
* 读取敏感词文件,并构建字典树
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
try {
InputStream in = Thread.currentThread().getContextClassLoader().
getResourceAsStream("sensitiveWords.txt");
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
String line = null;
while((line = br.readLine()) != null) {
addWord(br.readLine() );
}
isr.close();
} catch (Exception e) {
logger.error("读取敏感词文件失败" + e.getMessage());
}
}
/**
* 是否为非数字、大小写字母、汉字 字符
* @param ch
* @return
*/
private boolean isSymbol(char ch) {
return Pattern.matches("[^0-9a-zA-Z\u4e00-\u9fa5]", ""+ch);
}
/**
* 增加关键词
* @param lineText
*/
public void addWord(String lineText) {
TrieNode tmpNode = rootNode;
for(int i=0; i<lineText.length(); i++) {
Character ch = lineText.charAt(i);
if(isSymbol(ch))
continue;
TrieNode node = tmpNode.getSubNode(ch);
if(node == null) {
node = new TrieNode();
tmpNode.addSubNode(ch, node);
}
tmpNode = node;
if(i == lineText.length() - 1) {
tmpNode.setEnd(true);
}
}
}
/**
* 过滤敏感词
* @param text
* @return
*/
public String filter(String text) {
if(StringUtils.isEmpty(text)) {
return text;
}
StringBuilder result = new StringBuilder();
String replaceStr = "***";
TrieNode tmpNode = rootNode;
int begin = 0;
int position = 0;
while(position < text.length()) {
char ch = text.charAt(position);
if(isSymbol(ch)) {
if(tmpNode == rootNode) {
result.append(ch);
begin++;
}
position++;
continue;
}
tmpNode = tmpNode.getSubNode(ch);
if(tmpNode == null) {
result.append(text.charAt(begin));
position = begin + 1;
begin = position;
tmpNode = rootNode;
} else if(tmpNode.isEnd()) {
result.append(replaceStr);
position = position + 1;
begin = position;
tmpNode = rootNode;
} else {
position++;
}
}
result.append(text.substring(begin));
return result.toString();
}
}