`
bianku
  • 浏览: 71505 次
  • 性别: Icon_minigender_1
  • 来自: 常州
社区版块
存档分类
最新评论

关键字 过滤算法

阅读更多
因为过滤关键字机制到处可见,于是聪明的网友就会想到各种各样的方法突破,例如: 

1、中文会用繁体字的方法避开关键字扫描 
2、在关键字中间插入无意思的特殊字符,例如 * & # @ 等,而且个数可变 
3、使用谐音或拆字法变换关键字 

在实现自己的算法时也有些问题: 

4、随着时间推移,关键字列表会越来越大,有些论坛常用的正则表达式N次扫描的方法显得效率很低。 
5、关键字有不同的严重级别,有些需要禁止,有些只需要替换,还有一些可能记录一下即可。 


针对这些问题,可采用的应对方法: 

1、加载关键字列表时,将所有的关键字转换成繁体字一份,以扫描繁体版的关键字; 
这个转换工作只需一句就可以实现了: 
s=Microsoft.VisualBasic.Strings.StrConv(word, Microsoft.VisualBasic.VbStrConv.TraditionalChinese, 0); 

2、在扫描原文本时,如果遇到关键字的首个文字,忽略其后的特殊字符,直到下一个有意义的文字为止,当然这里需要在定义关键字列表时指定哪些才需要这样扫描,并不是所有关键字都采用这种方式; 
例如有关键字 “你好”经常会被人输入成“你x好”或者“你xxxxx好”,那么在关键字列表里就需要定义成“你*好”,在匹配关键字时,如果遇到星号就忽略原文本下一个为特殊的字符。 

3、遇到谐音和拆字时,没什么好办法了,只好将这些谐音词和拆分词也加入到关键字列表。 

4、不用正则表达式或者 String.IndexOf方法,可以将所有关键字的首字相同的组成一个一个小组,然后在将首字放到一个散列表(HashTable/Dictionary<T>),在扫描原文本时先在散列表里扫描,如果碰到了首字再扫描同组的关键字,这样简单处理一下效率可以提高很多。 



还有一个比用散列表更好的方法,将散列表改成一个大小为char.MaxValue的数组,然后将首个文字转成int,即char->int,然后将关键词集合放到相应下标里。这样在扫描原文本时,将被扫描的字符转成int,然后试探数组相应下标的元素是否不为NULL。这样比用散列表会更快一些。 

5、在定义关键字时,同时给一个“级别”属性,例如使用 E,R,B分别表示只记录、替换、禁止等情况。 
于是关键字的列表如下所示: 
你滚 E 
他niang的 R 
成*人*网*站 B 

这里贴一下关键的部分代码: 



Code 
private WordGroup[] _wordTable; 

public FilterResult Filter(ref string source,char replaceChar) 
{ 
//NOTE:: 
// 如果方法返回 FilterResult.Replace或者FilterResult.Banned,则原字符串的某些字会被替代为星号,替代后的字符串可以由source取得 

if (String.IsNullOrEmpty(source)) return FilterResult.Pass; 

FilterResult result = FilterResult.Pass; 
char[] tempString = null; 

int start = 0; 
for (; start < source.Length; start++) 
{ 
WordGroup fw = _wordTable[fastToLower(source[start])]; 
if (fw != null) 
{ 
for (int idx = 0; idx < fw.Count; idx++) 
{ 
WordEntity we = fw.GetItem(idx); 
int matchLength=0; 
if (we.Word.Length==0 || checkString(source, we.Word, start + 1, out matchLength)) 
{ 
FilterResult fr = we.HandleType; 
if (fr > result) result = fr; //记录最高级别的处理方法 
if (fr == FilterResult.Replace || fr == FilterResult.Banned) 
{ 
//替换关键字 
if(tempString==null) tempString =source.ToCharArray();; 
for (int pos = 0; pos < matchLength + 1; pos++) 
{ 
tempString[pos + start] = replaceChar; 
} 
} 
} 
} 
} 
} 

if (result > FilterResult.RecordOnly) 
{ 
source = new string(tempString); 
} 

return result; 
} 

private bool checkString(string source, string keyword, int sourceStart, out int matchLength) 
{ 
bool found = false; 
int sourceOffset = 0; 
int keyIndex = 0; 
for (; keyIndex < keyword.Length; keyIndex++) 
{ 
if (sourceOffset + sourceStart >= source.Length) break; //原始字符串已经全部搜索完毕 

if (keyword[keyIndex] == '*') 
{ 
//跳过可忽略的字符 
while (sourceOffset + sourceStart < source.Length) 
{ 
if (isIgnorableCharacter_CN(source[sourceOffset + sourceStart])) 
sourceOffset++; 
else 
break; 
} 
} 
else 
{ 
//比较字母 
if (fastToLower(source[sourceOffset + sourceStart]) == (int)keyword[keyIndex]) 
{ 
if (keyIndex == keyword.Length - 1) 
{ 
found = true; 
break; 
} 
} 
else 
{ 
break; 
} 

sourceOffset++;//移动原始字符串 
} 
} 

//如果匹配中关键字,则返回原字符串中被匹配中的文字的长度,否则返回0 
matchLength = sourceOffset + 1; 
return found; 
} 

private int fastToLower(char character) 
{ 
//将大写英文字母以及全/半角的英文字母转化为小写字母 
int charVal = (int)character; 
if (charVal <= 90) 
{ 
if (charVal >= 65) //字母A-Z 
return charVal - 65 + 97; 
} 
else if (charVal >= 65313) 
{ 
if (charVal <= 65338) 
return charVal - 65313 + 97; //全角大写A-Z 
else if (charVal >= 65345 && charVal <= 65370) 
return charVal - 65345 + 97; //全角小写a-z 
} 
return charVal; 
} 

private bool isIgnorableCharacter_CN(char character) 
{ 
//NOTE:: 
// 中文表意字符的范围 4E00-9FA5 
int charVal = (int)character; 
return !(charVal >= 0x4e00 && charVal <= 0x9fa5); 
} 

// 单个过滤词条目 
class WordEntity 
{ 
public string Word { get; set; } 
public FilterResult HandleType { get; set; } 
} 

// 过滤词的组 
class WordGroup 
{ 
//NOTE::用于装载一组具有同一个字开头的过滤词 

private List<WordEntity> _words; 

public WordGroup() 
{ 
_words = new List<WordEntity>(); 
} 

public void AppendWord(string word, FilterResult handleType) 
{ 
AppendWord(new WordEntity() { Word = word, HandleType = handleType }); 
} 

public void AppendWord(WordEntity word) 
{ 
_words.Add(word); 
} 

public int Count 
{ 
get { return _words.Count; } 
} 

public WordEntity GetItem(int index) 
{ 
return _words[index]; 
} 
} 

 

分享到:
评论
1 楼 啸笑天 2010-05-03  

相关推荐

    关键字过滤算法

    关键字过滤算法 本文档描述的是一个关于关键字过滤的算法,该算法不同于其他过滤算法的是,它是一个中英文混合过滤算法。该算法的关键点在于构造一个完全哈希树,以便快速匹配关键字。 首先,我们需要构造一个哈希...

    关键字过滤多模式匹配算法(支持中文)

    本文将详细探讨这些知识点,并结合“关键字过滤多模式匹配算法(支持中文)”这一主题,深入解析相关技术和应用。 首先,关键字过滤是一种技术,用于从大量文本数据中筛选出包含特定关键字或短语的信息。这种技术...

    高效关键字过滤java源码

    最近项目中要用到关键字过滤,就参考网上的算法自己写了个关键字过滤的java代码,思路如下: 将关键词的第1个字作为hashMap的索引,第2个字放到另一个hashMap中,并让第1个字的索引指向这个hashMap 过滤关键字的...

    网站关键字过滤词库

    网站关键字过滤词库是用于网页内容审核和管理的重要工具,主要目的是防止不适当、违法或敏感的词汇出现在网站上,确保网络环境的纯净和合规。这些词库通常包含一系列预先定义的关键字,当用户在网站上发布内容时,...

    关键字过滤 效率够快

    总之,关键字过滤是信息技术中一个实用且高效的工具,它依赖于精心设计的关键字库和高效的算法实现,同时结合优化策略来提升性能。在处理大量文本数据时,理解并掌握这些核心要素对于提升系统性能至关重要。

    文本中关键字匹配算法的实现

    本话题将深入探讨关键字匹配算法的实现及其重要性。 关键字匹配的基本目标是从文本集合中找出所有包含指定关键字的文档或段落。这通常涉及到字符串匹配,即在给定的文本串中寻找目标关键字串的过程。字符串匹配算法...

    jsp页面中关键字过滤函数

    在开发Web应用,尤其是搭建论坛或社区类网站时,关键字过滤是一个重要的功能模块。它主要用于防止用户发布含有敏感词汇或不适宜内容的信息,确保网络环境的健康与和谐。本项目中,我们关注的是如何在JSP(Java ...

    指定数据库关键字过滤

    总的来说,"指定数据库关键字过滤"项目涉及了数据库管理、数据结构、算法优化、并行计算和软件工程等多个领域的知识,是实现大数据量高效检索的典型案例。在实际应用中,这样的技术可以帮助企业快速响应用户需求,...

    基于jsp的非法关键字过滤功能

    本项目"基于jsp的非法关键字过滤功能"专注于使用JavaServer Pages(JSP)来实现这一功能,对于学习如何在Web应用中实施安全策略的开发者来说具有很高的参考价值。 JSP是Java平台上的一个服务器端脚本语言,它允许...

    soft_非法关键字过滤器 v2.2 .zip.zip

    《soft_非法关键字过滤器 v2.2 .zip.zip》是一款专用于文本内容审查和净化的软件工具,其主要功能是检测并过滤掉文本中的非法或敏感关键字。在这个压缩包中,有两个文件:output.txt和“非法关键字过滤器 v2.2 .zip...

    XML流上的关键字查询算法

    ### XML流上的关键字查询算法 #### 概述 随着互联网技术的发展,XML(Extensible Markup Language,可扩展标记语言)已成为一种广泛应用于数据存储和交换的标准格式。在各种基于XML的应用场景中,如股票交易信息...

    关键字查找算法

    标题中的“关键字查找算法”指的是在数据结构和算法领域中,用于快速定位和检索特定关键字的方法。这种算法在处理大量文本数据时尤为重要,比如搜索引擎、敏感词过滤等场景。描述中提到的“用多叉树实现”,暗示了...

    基于ASP的非法关键字过滤管理系统 v1.0.zip

    非法关键字过滤管理系统是一种用于监控和阻止含有特定敏感词汇的网络内容发布的工具。在互联网环境中,这种系统通常用于论坛、博客、社交媒体等平台,以防止不良信息的传播,维护网络安全和秩序。系统通过比对用户...

    基于compKey的关键字推荐算法以及前端页面部分

    例如,协同过滤算法会预测用户可能对哪些未被发现的关键词感兴趣。 5. **评估与优化**:通过A/B测试、点击率等指标评估推荐效果,并不断调整算法参数以优化推荐质量。 接下来是“前端页面部分”,这部分涉及网页...

    jQuery过滤关键字插件

    jQuery过滤关键字插件是一种在网页中实现快速搜索和筛选功能的工具,主要应用于动态数据列表或大型数据集合的实时过滤。在这个场景下,用户输入关键字时,插件能够即时更新显示的内容,只展示与关键字匹配的元素。在...

    基于协同过滤算法的个性化新闻推荐系统-毕业设计说明书1

    【协同过滤算法】 协同过滤(Collaborative Filtering,简称CF)是一种广泛应用于推荐系统中的机器学习算法。它基于用户的历史行为数据,通过发现用户之间的相似性或物品之间的相似性来预测用户对未知物品的评分或...

    使用类别和关键字进行个性化推荐:可扩展的协作过滤算法

    使用类别和关键字进行个性化推荐:可扩展的协作过滤算法

Global site tag (gtag.js) - Google Analytics