当前网络环境下,网友的力量真是不容忽视,一个不小心,整个网站或论坛就成了垃圾信息的集散地。为了保证网站的清洁,需要开发一个过滤词功能,灵活控制网站提交的信息。
最初的设计是所有回复和留言均需要审核,对于信息量小的来说,还能应用,但是对于信息量大的网站或论坛来说,工作量可想而知,参看了传智播客中介绍的过滤词相关功能,仿写了一个,主要功能:实现可配置过滤词、敏感词、替换词、审核词以控制提交回来的信息,如果检查通过,直接入库并显示。
历史时期见过将所有相关过滤词均放入到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
}