射击游戏项目开发笔记 (五)
字符屏蔽似乎是在我朝才有的东西.这屏蔽那屏蔽的,干脆彻底把Internet变成Local Area Network得了(虽然现在对大部分人来说已经是Local Area Network了).如果说我有什么职业梦想的话,The Great Wall崩塌估计是我唯一的梦想了.
在目前国内游戏的字符屏蔽中,主要是分为:聊天屏蔽(过滤词语) 和 命名屏蔽(过滤词语+过滤特殊标点符号)
过滤词语
首先看以下趣图:
图的出处无法考量,但是之所以引发这种笑话 就是字符过滤做得不够严谨导致的.程序员把所有带 草 的字符都替换成了其他字符,这里是星号.所以过滤词语需要引入列表分级的方式.由于汉语的特殊性,使得其中一部分词语,会成为另外一部分词语中的组成部分。例如:“西藏”、属于屏蔽列表范围;但“东躲西藏”这些成语里虽然里面包含了“西藏”字符,却是完全不同的含义。针对这种状况,屏蔽列表分为两级。
列表分级:
第一层为屏蔽字列表。当玩家输入的文字中,不属于第一层不过滤列表,又属于过滤列表时,则判定为非法字符,需重新输入。
第二层为不过滤列表。当玩家输入的文字中,出现不过滤列表中的字符,则,该列表中对应的文字将不属于屏蔽字。
例如上图 草 属于屏蔽字列表,但粮草先行的意思于单字草完全是两种意思(汉字真博大精深),所以粮草先行需要加入不过滤列表.
词语过滤的主要代码如下
// C# m_DictSensitiveWord.add("西藏","东躲西藏;西藏东躲"); string str = "我在西藏东躲西藏"; bool done = true; int nSize = str.Length; foreach (KeyValuePairp in m_DictSensitiveWord) { int nIndex1 = str.IndexOf(p.Key); int nKeySize = p.Key.Length; int nNextIndex = 0; string[] sArray = null; while (-1 != nIndex1 && nIndex1 < nSize && true == done) { done = false; if (null == p.Value) { break; } if (null == sArray) { sArray = p.Value.Split(';'); } for (int i = 0; i < sArray.Length; ++i ) { int nIndex2 = str.IndexOf(sArray[i], nNextIndex); if (-1 == nIndex2) { continue; } int nValueSize = sArray[i].Length; if (nIndex2 <= nIndex1 && (nIndex1 + nKeySize <= nIndex2 + nValueSize)) { nNextIndex = nValueSize - sArray[i].IndexOf(p.Key); done = true; break; } } nNextIndex += nIndex1; nIndex1 = str.IndexOf(p.Key, nIndex1 + nKeySize); } if (!done) { break; } } if(done) { // 有敏感字符... }
测试一下效果:
过滤标点
在游戏中玩家命名,各种工会命名是不允许出现标点符号的,所以在这种情况下需要进行标点符号过滤.标点过滤就非常简单了.这里不详细描述.
JS的话怎么写呀?