前端之家收集整理的这篇文章主要介绍了
敏感词过滤 DFA 状态机 cocos2d-js 实现版,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
// 定义命名空间
var GameClient = GameClient || {};
// DFA 实现敏感词过滤 // improve from http://blog.sina.com.cn/s/blog_53f6148101016wq1.html
GameClient.FilterWord = cc.Class.extend({
m_wordList: null,// @private
m_map: null,// @private
ctor: function (wordList) {
if (wordList == null) {
wordList = [];
}
// cc.warn("wordList: %o",wordList);
this.m_wordList = wordList;
this.m_map = this.BuildMap(wordList);
},// 替换 str 中的敏感词为 replaceStr,step 为筛选强度, 最小为 0,最大为 5
RunFilterWord: function (str,replaceStr,step) {
if (str == undefined) {
return "";
}
if (step > 5) {
step = 5;
}
if (step < 0) {
step = 0;
}
for (var j = 0; j < step; j++) {
var result = this.Check(this.m_map,str);
// 排序结果,长度长的在前面
result.sort(function(a,b){
return b.length - a.length});
console.log("result: " + result);
for (var i = 0; i < result.length; i++) {
str = str.replace(result[i],replaceStr);
}
}
return str;
},// @private
BuildMap: function (wordList) {
var result = {};
var count = wordList.length;
// 遍历单词
for (var i = 0; i < count; ++i) {
var map = result;
var word = wordList[i];
var wordLength = word.length;
// 遍历单词的每个字母
for (var j = 0; j < wordLength; ++j) {
var ch = word.charAt(j);
var stateInfo = map[ch];
if (stateInfo == null) {
stateInfo = {};
map[ch] = stateInfo;
}
// 如果是最后一个字母,设置一个完结标识
if (j == wordLength - 1) {
stateInfo["isFinish"] = true;
}
else {
map = stateInfo;
}
}
}
return result;
},// @private // 找出 content 中的敏感词,会返回一个包含敏感词的列表
Check: function (map,content) {
var result = [];
var count = content.length;
var stack = [];
var point = map;
// 用于标记找到关键词的标记
var isFound = false;
var foundStack = null;
for (var i = 0; i < count; ++i) {
var ch = content.charAt(i);
var item = point[ch];
// 如果没找到则复位,让主循环
if (item == null) {
if (isFound) {
isFound = false;
i = i - (stack.length - foundStack.length + 1); // 计算回退距离
result.push(foundStack.join("")); // 把单个的字母数组连成一串字符串
}
else {
i = i - stack.length; // 计算回退距离
}
stack = []; // 清空字符堆栈
point = map;
}
else if (item["isFinish"]) {
stack.push(ch);
point = item;
// 标记找到了目标词
isFound = true;
foundStack = stack.concat(); // 复制数组
}
else {
stack.push(ch);
point = item;
}
}
// 这里还要补充检查
if (isFound) {
result.push(foundStack.join("")); // 把单个的字母数组连成一串字符串
}
return result;
},Destroy: function () {
this.m_wordList = null;
this.m_map = null;
}
});
var filterWord = new GameClient.FilterWord(["ab","bad","abc","ddd","aaa","ccc","bbb","adsf","edsdf","ss","fff","aaa"]);
console.log("1: " + filterWord.RunFilterWord("asdfsdsddaadaaabbbffdassdf sdf bbb aaa a","#",1));
直接上
代码