当前网络环境下,网友的力量真是不容忽视,一个不小心,整个网站或论坛就成了垃圾信息的集散地。为了保证网站的清洁,需要开发一个过滤词功能,灵活控制网站提交的信息。
最初的设计是所有回复和留言均需要审核,对于信息量小的来说,还能应用,但是对于信息量大的网站或论坛来说,工作量可想而知,参看了传智播客中介绍的过滤词相关功能,仿写了一个,主要功能:实现可配置过滤词、敏感词、替换词、审核词以控制提交回来的信息,如果检查通过,直接入库并显示。
历史时期见过将所有相关过滤词均放入到web.config,第一反应就是,控制性差。本过滤词功能利用正则实现匹配,同时改进了传智中的某些地方,适应性更强,能正常满足一般的需要。下面来始贴代码:
环境:VS2012+MSSQL2005下通过
第一步:建数据表
CREATE TABLE [dbo].[TheFilterWord]( [FilterWordID] [int] IDENTITY(1,1) NOT NULL, [FilterWord] [varchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL, [ReplaceWord] [nvarchar](30) COLLATE Chinese_PRC_CI_AS NOT NULL, CONSTRAINT [PK_FilterWord] PRIMARY KEY CLUSTERED ( [FilterWordID] ASC )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY]
第二步:实现操作类,核心部分
public class TheFilterWordDAL { SqlHelp sqlhelp = null; List<TheFilterWord> list; public TheFilterWordDAL() { sqlhelp = new SqlHelp(); } #region 增加TheFilterWord /// <summary> /// 添加TheFilterWord记录 /// </summary> /// <param name="TheFilterWord">TheFilterWord对象</param> /// <returns>添加TheFilterWord是否成功</returns> public bool InsertTheFilterWord(TheFilterWord TheFilterWord) { SqlParameter[] param = new SqlParameter[] { new SqlParameter ("@FilterWord",TheFilterWord.FilterWord),new SqlParameter ("@ReplaceWord",TheFilterWord.ReplaceWord) }; bool b = sqlhelp.ExecSql("USP_InsertTheFilterWord", param); if (b) { RemoveFilterWordsCache(TheFilterWord); } return b; } #endregion #region 删除TheFilterWord数据 /// <summary> /// 删除TheFilterWord记录 /// </summary> /// <param name="FilterWordIDs">主键值集合,如果有多个用逗号分隔</param> /// <returns>是否删除成功</returns> public bool DeleteTheFilterWord(string FilterWordIDs) { SqlParameter[] param = new SqlParameter[] { new SqlParameter("@FilterWordIDs",FilterWordIDs) }; bool b = sqlhelp.ExecSql("USP_DeleteTheFilterWord", param); if (b) { //因为有可能一次删除多条记录,但是又不明确是删除哪一种词,所以就把有关过滤词的缓存都清了 //清除过滤词相应的缓存 HttpRuntime.Cache.Remove("modRegExpr"); HttpRuntime.Cache.Remove("bannedRegExpr"); HttpRuntime.Cache.Remove("replaceRegExpr"); } return b; } #endregion #region 修改TheFilterWord /// <summary> /// 更改TheFilterWord /// </summary> /// <param name="TheFilterWord">TheFilterWord对象</param> /// <returns>更改TheFilterWord是否成功</returns> public bool UpdateTheFilterWord(TheFilterWord TheFilterWord) { SqlParameter[] param = new SqlParameter[] { new SqlParameter ("@FilterWordID",TheFilterWord.FilterWordID), new SqlParameter ("@FilterWord",TheFilterWord.FilterWord), new SqlParameter ("@ReplaceWord",TheFilterWord.ReplaceWord) }; bool b = sqlhelp.ExecSql("USP_UpdateTheFilterWord", param); if (b) { RemoveFilterWordsCache(TheFilterWord); } return b; } #endregion #region 根据过滤词查找自己 /// <summary> /// 通过过滤词查询自己 /// </summary> /// <param name="FilterWordID">过滤词</param> /// <returns>TheFilterWord对象</returns> public TheFilterWord GetTheFilterWordByFilterWord(string theFilterWord) { SqlParameter[] param = new SqlParameter[] { new SqlParameter ("@FilterWord",theFilterWord) }; SqlDataReader sdr = sqlhelp.GetReader("USP_GetTheFilterWordByFilterWord", param); TheFilterWord TheFilterWord = null; while (sdr.Read()) { TheFilterWord = new TheFilterWord() { FilterWordID = Convert.ToInt32(sdr["FilterWordID"].ToString()), FilterWord = sdr["FilterWord"].ToString(), ReplaceWord = sdr["ReplaceWord"].ToString() }; } sdr.Close(); return TheFilterWord; } #endregion #region 获取TheFilterWord表中所有数据 /// <summary> /// 获取TheFilterWord表中所有数据 /// </summary> public List<TheFilterWord> GetAllTheFilterWordData() { SqlDataReader sdr = sqlhelp.GetReader("USP_GetAllTheFilterWordData"); ToList(sdr); sdr.Close(); return list; } /// <summary> /// 得到所有的禁用词 /// </summary> /// <returns></returns> public List<TheFilterWord> GetAllBannedWords() { SqlDataReader sdr = sqlhelp.GetReader("GetBannedWords"); ToList(sdr); sdr.Close(); return list; } /// <summary> /// 得到所有的审核词 /// </summary> /// <returns></returns> public List<TheFilterWord> GetAllModWords() { SqlDataReader sdr = sqlhelp.GetReader("GetModWords"); ToList(sdr); sdr.Close(); return list; } /// <summary> /// 得到所有的替换词 /// </summary> /// <returns></returns> public List<TheFilterWord> GetAllReplaceWords() { SqlDataReader sdr = sqlhelp.GetReader("GetReplaceWords"); ToList(sdr); sdr.Close(); return list; } #endregion #region 将SQLDataReader转为list /// <summary> /// 把DataReader转为list<TheFilterWord> /// </summary> /// <param name="sdr">SQLDataReader</param> /// <returns>List<TheFilterWord></returns> protected void ToList(SqlDataReader sdr) { list = new List<TheFilterWord>(); TheFilterWord thefilterword = null; while (sdr.Read()) { thefilterword = new TheFilterWord() { FilterWordID = Convert.ToInt32(sdr["FilterWordID"].ToString()), FilterWord = sdr["FilterWord"].ToString(), ReplaceWord = sdr["ReplaceWord"].ToString() // }; list.Add(thefilterword); } } #endregion #region 得到过滤结果 /// <summary> /// 得到过滤结果 /// </summary> /// <param name="sourceContent">输入内容</param> /// <param name="regstr"></param> /// <returns></returns> public FilterType GetFiltedResult(string sourceContent, out string result) { TheFilterWordDAL fwop = new TheFilterWordDAL(); list = fwop.GetAllBannedWords(); result = sourceContent; string regPatten = ""; //替换词处理,经考虑放在后两个判断前 if (HttpRuntime.Cache["replaceRegExpr"] != null) { list = (List<TheFilterWord>)HttpRuntime.Cache["replaceRegExpr"]; } else { list = fwop.GetAllReplaceWords(); HttpRuntime.Cache["replaceRegExpr"] = list; } if (list.Count > 0) { foreach (TheFilterWord item in list) { result.Replace(item.FilterWord, item.ReplaceWord); } } //对禁用词进行操作 regPatten = GetBannedRegExpression(); if (!string.IsNullOrEmpty(regPatten)) { if (Regex.IsMatch(result, regPatten)) { return FilterType.BANNED; } } //审核词处理************************* regPatten = GetBannedRegExpression(); if (!string.IsNullOrEmpty(regPatten)) { if (Regex.IsMatch(result, regPatten)) { //有审核词的处理 return FilterType.Mod; } } return FilterType.OK; } #endregion #region 获取禁用词正则表达式 //得到禁用词的正则表达式 protected string GetBannedRegExpression() { //禁用词处理************************* if (HttpRuntime.Cache["bannedRegExpr"] != null) { return Convert.ToString(HttpRuntime.Cache["bannedRegExpr"]); } string bannedRegExpression = ""; list = GetAllBannedWords(); if (list.Count > 0) { foreach (TheFilterWord item in list) { bannedRegExpression += item.FilterWord + "|"; } //构造表达式 bannedRegExpression = bannedRegExpression.Trim(‘|‘); bannedRegExpression = Regex.Replace(bannedRegExpression.Replace(@".", @"\."), @"\{([^}]+)\}", ".{0,$1}").Replace(@"\", @"\\"); //加入缓存; HttpRuntime.Cache.Insert("bannedRegExpr", bannedRegExpression); } return bannedRegExpression; } #endregion #region 获取禁用词正则表达式 //得到审核词的正则表达式 protected string GetModRegExpression() { if (HttpRuntime.Cache["modRegExpr"] != null) { return Convert.ToString(HttpRuntime.Cache["modRegExpr"]); } string modRegExpression = ""; list = GetAllModWords(); string[] ModWords = list.Select(o => o.FilterWord).ToArray(); if (ModWords.Length > 0) { modRegExpression = string.Join("|", ModWords); modRegExpression = Regex.Replace(modRegExpression.Replace(@".", @"\."), @"\{([^}]+)\}", ".{0,$1}").Replace(@"\", @"\\"); } HttpRuntime.Cache.Insert("modRegExpr", modRegExpression); return modRegExpression; } #endregion #region 从流中导入过滤词 public void ImportFilterWords(Stream stream) { using (StreamReader reader = new StreamReader(stream, Encoding.Default)) { string line; while (!string.IsNullOrEmpty(line = reader.ReadLine())) { string[] strs = line.Split(‘=‘); string word = strs[0]; string replaceWord = strs[1]; //判断是否已经存在。存在则更新,不存在直接插入 TheFilterWord filterWord = GetTheFilterWordByFilterWord(word); if (filterWord == null) { filterWord = new TheFilterWord(); filterWord.ReplaceWord = replaceWord; filterWord.FilterWord = word; InsertTheFilterWord(filterWord); } else { //如果存在则更新 filterWord.ReplaceWord = replaceWord; filterWord.FilterWord = word; UpdateTheFilterWord(filterWord); } } } //清除过滤词相应的缓存 HttpRuntime.Cache.Remove("modRegExpr"); HttpRuntime.Cache.Remove("bannedRegExpr"); HttpRuntime.Cache.Remove("replaceRegExpr"); } #endregion #region 更改或是删除或是添加以后根据条件来移出相应的缓存 public void RemoveFilterWordsCache(TheFilterWord thefilterword) { if (thefilterword.ReplaceWord.ToLower() == "{banned}") { HttpRuntime.Cache.Remove("bannedRegExpr"); } else if (thefilterword.ReplaceWord.ToLower() == "{mod}") { HttpRuntime.Cache.Remove("modRegExpr"); } else { HttpRuntime.Cache.Remove("replaceRegExpr"); } } #endregion #region 根据主键主值查找自己 /// <summary> /// 通过主键FilterWordID来获取TheFilterWord对象 /// </summary> /// <param name="FilterWordID">主键FilterWordID值</param> /// <returns>TheFilterWord对象</returns> public TheFilterWord GetTheFilterWordByPKFilterWordID(int FilterWordID) { SqlParameter[] param = new SqlParameter[] { new SqlParameter ("@FilterWordID",FilterWordID) }; SqlDataReader sdr = sqlhelp.GetReader("USP_GetTheFilterWordByPK_FilterWordID", param); TheFilterWord TheFilterWord = null; while (sdr.Read()) { TheFilterWord = new TheFilterWord() { FilterWordID = Convert.ToInt32(sdr["FilterWordID"].ToString()), FilterWord = sdr["FilterWord"].ToString(), ReplaceWord = sdr["ReplaceWord"].ToString() }; } sdr.Close(); return TheFilterWord; } #endregion }
这里涉及到的SQL查询:
if object_id(‘USP_GetData‘) is not null drop proc USP_GetData go create PROC USP_GetData(@source VARCHAR(500),@searchFields VARCHAR(200), @condition varchar(500),@orderby NVARCHAR(200), @pageIndex int,@pageSize INT,@RecordCount INT OUTPUT) AS IF LEN( REPLACE(@searchFields,‘ ‘,‘‘))=0 BEGIN set @searchFields=‘*‘ END DECLARE @begin VARCHAR(30) SET @begin=(@pageIndex-1)*@pageSize+1 DECLARE @end VARCHAR(30) SET @end=@pageIndex*@pageSize DECLARE @sql VARCHAR(800) SET @sql=‘ SELECT * FROM (SELECT ROW_NUMBER() OVER ( order by ‘+ @orderby+‘ ) AS theorder, ‘+ @searchFields +‘ FROM ‘+@source+‘ WHERE 1=1‘+ @condition+‘ ) as a WHERE theorder BETWEEN ‘+@begin+‘ and ‘+ @end Declare @SqlQueryCount NVARCHAR(MAX) SET @SqlQueryCount = ‘SELECT @COUNT = count(*) FROM ‘+@source+‘ where 1=1 ‘+@condition execute sp_executesql @SqlQueryCount, N‘@COUNT int output‘, @RecordCount OUTPUT EXECUTE (@sql) go --增加表TheFilterWord数据 if object_id(‘USP_InsertTheFilterWord‘) is not null drop proc USP_InsertTheFilterWord go create proc USP_InsertTheFilterWord( @FilterWord varchar(50),@ReplaceWord nvarchar(30) ) as insert into TheFilterWord(FilterWord,ReplaceWord) values (@FilterWord,@ReplaceWord) go --修改表TheFilterWord数据 if object_id(‘USP_UpdateTheFilterWord‘) is not null drop proc USP_UpdateTheFilterWord go create proc USP_UpdateTheFilterWord( @FilterWordID int,@FilterWord varchar(50),@ReplaceWord nvarchar(30) ) as update TheFilterWord set FilterWord=@FilterWord,ReplaceWord=@ReplaceWord where FilterWordID=@FilterWordID go /*删除数据*/ if object_id(‘USP_DeleteTheFilterWord‘) is not null drop proc USP_DeleteTheFilterWord GO CREATE PROC USP_DeleteTheFilterWord(@FilterWordIDs VARCHAR(max)) AS DELETE FROM TheFilterWord WHERE FilterWordID IN (@FilterWordIDs) go /*根据主键查找自己*/ if object_id(‘USP_GetTheFilterWordByPk_FilterWordID‘) is not null drop proc USP_GetTheFilterWordByPk_FilterWordID GO CREATE PROC USP_GetTheFilterWordByPk_FilterWordID(@FilterWordID int) AS SELECT * FROM TheFilterWord WHERE FilterWordID=@FilterWordID GO if object_id(‘USP_GetTheFilterWordByFilterWord‘) is not null drop proc USP_GetTheFilterWordByFilterWord GO CREATE PROC USP_GetTheFilterWordByFilterWord(@FilterWord varchar(20)) AS SELECT * FROM TheFilterWord WHERE FilterWord=@FilterWord GO /*得到所有的过滤词*/ create PROC USP_GetAllTheFilterWordData AS SELECT * FROM TheFilterWord go /*得到禁用词*/ CREATE PROC GetBannedWords as SELECT * FROM TheFilterWord tfw WHERE tfw.ReplaceWord=‘{Banned}‘ GO /*得到审核词*/ CREATE PROC GetModWords as SELECT * FROM TheFilterWord tfw WHERE tfw.ReplaceWord=‘{MOD}‘ GO /*得到替换词*/ CREATE PROC GetReplaceWords as SELECT * FROM TheFilterWord tfw WHERE tfw.ReplaceWord<>‘{MOD}‘ AND tfw.ReplaceWord<>‘{Banned}‘ GO
实体类:
public class TheFilterWord { public int FilterWordID { get; set; } //编号 public string FilterWord { get; set; } //词 public string ReplaceWord { get; set; } //ReplaceWord为替换词,如果是禁用词,则此列统一为"{Banned}",如果为审批词, //则此列为"{MOD}",如果为替换词,此列值为要用来替换的词内容 }
第三步:引用控制
//提交 protected void btnSubmit_Click(object sender, EventArgs e) { string FilterResult=""; FilterType result = fwop.GetFiltedResult(txtContent.Text, out FilterResult); if (result ==FilterType .BANNED) //有禁用词 { } else if (result == FilterType.Mod) //有审核词 { } else //可以入库,最多只有替换词 { } }
引用到一个枚举:
/// <summary> /// 过滤返回值 /// </summary> public enum FilterType { BANNED, Mod, OK }
原文:http://www.cnblogs.com/MoWu/p/4877634.html