关键字过滤
最近写了一个关键字过滤器,也就是脏字过滤,由于是新手,所以效率大家可能不敢恭维。
不过总算是实现了哈。
对于保存脏字的字典,用的是NameValueCollection,他的结构大概为下图:
一个键值组合,
一个键能对应多个值,
这就使得我们第一次
的匹配能减少很多次。
按照这个结构,我们把关键字的字典读取,每次增加关键字都会历遍Key组,如果相对应的Key已经存在,
则把值添加到对应Key的值组里面,如果不存在则创建新的Key来存放值。
下面是我的流程图:

然后是测试的效率:


最后是实现的代码,需要的兄弟可以用用,但不保证效率哈~
1
using System;
2
using System.Collections.Specialized;
3
using System.Xml;
4
using System.Text;
5
using System.IO;
6![]()
7
namespace KeyWordFilter
8
{
9![]()
10
/// <summary>
11
/// 脏字过滤
12
/// 脏字字典需命名后放在根目录下。
13
/// </summary>
14
public class KeyWordFilter
15
{
16
//保存脏字的字典
17
private NameValueCollection KeyWordDictionary = new NameValueCollection();
18![]()
19
public KeyWordFilter()
20
{
21
//初始化脏字字典
22
GetAllTheKeyWord();
23
}
24![]()
25![]()
26![]()
27
private void GetAllTheKeyWord()
28
{
29
String KeyWord = "";
30![]()
31
XmlDocument xmlDocument = new XmlDocument();
32![]()
33
//配置信息,保存脏字字典的位置及名称
34
xmlDocument.Load("Config.xml");
35
XmlNode node = xmlDocument.DocumentElement;
36![]()
37
//脏字字典地址
38
string File_Name = node.SelectNodes("KeyWordDictionary").Item(0).InnerText.ToString();
39![]()
40
//string File_Name = @".\Dictionary.txt";
41![]()
42
//文件存在则开始读取
43
if (File.Exists(File_Name))
44
{
45
//读取脏字符
46
StreamReader reader = new StreamReader(File_Name, System.Text.Encoding.GetEncoding("gb2312"));
47
String input = "";
48
while (reader.Peek() > 1)
49
{
50
input = (reader.ReadLine());
51![]()
52
//将脏字首字作为键,后续的字符串作为值
53
KeyWordDictionary.Add(input[0].ToString(), input.ToString().Substring(1, input.Length - 1));
54
input = string.Empty;
55
}
56
}
57
}
58![]()
59
public String CheckTheText(String input)
60
{
61
//保存新字符的StringBuilder
62
StringBuilder newString = new StringBuilder();
63
int i = 0;
64![]()
65
//如果脏字字典不为空,则
66
//历遍input,检查是否有非法字
67
if (KeyWordDictionary.Keys.Count != 0)
68
{
69
for (i = 0; i < input.Length; )
70
{
71![]()
72
foreach (string key in KeyWordDictionary.AllKeys)
73
{
74
if (i < input.Length)
75
{
76
//input的当前字符是否在脏字字典的键组中
77
if (input[i].ToString() == key)
78
{
79
//历遍当前键所在的脏字值组
80
foreach (string word in KeyWordDictionary.GetValues(key))
81
{
82![]()
83
if ((i + word.Length) < input.Length)
84
{
85
//从当前位置开始,截取与当前值相同长度的字符串与
86
//当前脏字比较
87
if (input.Substring(i + 1, word.Length) == word)
88
{
89
//如果符合则替换与脏字相同长度的字符
90
newString.Append(ChangeTheWords(input[i], word.Length));
91
i += word.Length + 1;
92
break;
93
}
94
else
95
{
96
//如果匹配到最后一个仍未有脏字,则把当前字符加入输出字符串
97
if (word == KeyWordDictionary.GetValues(key)[KeyWordDictionary.GetValues(key).Length - 1])
98
{
99
newString.Append(input[i]);
100
i++;
101
}
102
}
103
}
104
else { } //如果下个需要匹配的脏字超过了剩下了字符长度,则跳过当前脏字符.
105![]()
106
}
107
}
108
//如果没有键与当前字符匹配,则把当前字符加入输出字符串
109
else if (key == KeyWordDictionary.AllKeys[KeyWordDictionary.Keys.Count - 1])
110
{
111
newString.Append(input[i]);
112
i++;
113
}
114
}
115
//catch (Exception e) { }
116![]()
117
}
118
}
119
}
120
else newString.Append(input); //如果脏字字典为空,则返回原文
121![]()
122
return newString.ToString();
123
}
124![]()
125
//根据传入的长度生成屏蔽符号
126
private string ChangeTheWords(char input, int length)
127
{
128
StringBuilder newString = new StringBuilder();
129![]()
130
newString.Append(input);
131![]()
132
for (int i = 0; i < length; i++)
133
{
134
newString.Append("*");
135
}
136
return newString.ToString();
137
}
138
}
139
}
140![]()
using System;2
using System.Collections.Specialized;3
using System.Xml;4
using System.Text;5
using System.IO;6

7
namespace KeyWordFilter8
{9

10
/// <summary>11
/// 脏字过滤12
/// 脏字字典需命名后放在根目录下。13
/// </summary>14
public class KeyWordFilter15
{16
//保存脏字的字典17
private NameValueCollection KeyWordDictionary = new NameValueCollection();18

19
public KeyWordFilter()20
{21
//初始化脏字字典22
GetAllTheKeyWord();23
}24

25

26

27
private void GetAllTheKeyWord()28
{29
String KeyWord = "";30

31
XmlDocument xmlDocument = new XmlDocument();32

33
//配置信息,保存脏字字典的位置及名称34
xmlDocument.Load("Config.xml");35
XmlNode node = xmlDocument.DocumentElement;36

37
//脏字字典地址38
string File_Name = node.SelectNodes("KeyWordDictionary").Item(0).InnerText.ToString();39

40
//string File_Name = @".\Dictionary.txt";41

42
//文件存在则开始读取43
if (File.Exists(File_Name))44
{45
//读取脏字符46
StreamReader reader = new StreamReader(File_Name, System.Text.Encoding.GetEncoding("gb2312"));47
String input = "";48
while (reader.Peek() > 1)49
{50
input = (reader.ReadLine());51

52
//将脏字首字作为键,后续的字符串作为值53
KeyWordDictionary.Add(input[0].ToString(), input.ToString().Substring(1, input.Length - 1));54
input = string.Empty;55
}56
}57
}58

59
public String CheckTheText(String input)60
{61
//保存新字符的StringBuilder62
StringBuilder newString = new StringBuilder();63
int i = 0;64

65
//如果脏字字典不为空,则66
//历遍input,检查是否有非法字67
if (KeyWordDictionary.Keys.Count != 0)68
{69
for (i = 0; i < input.Length; )70
{71

72
foreach (string key in KeyWordDictionary.AllKeys)73
{74
if (i < input.Length)75
{76
//input的当前字符是否在脏字字典的键组中77
if (input[i].ToString() == key)78
{79
//历遍当前键所在的脏字值组80
foreach (string word in KeyWordDictionary.GetValues(key))81
{82

83
if ((i + word.Length) < input.Length)84
{85
//从当前位置开始,截取与当前值相同长度的字符串与86
//当前脏字比较87
if (input.Substring(i + 1, word.Length) == word)88
{89
//如果符合则替换与脏字相同长度的字符90
newString.Append(ChangeTheWords(input[i], word.Length));91
i += word.Length + 1;92
break;93
}94
else95
{96
//如果匹配到最后一个仍未有脏字,则把当前字符加入输出字符串97
if (word == KeyWordDictionary.GetValues(key)[KeyWordDictionary.GetValues(key).Length - 1])98
{99
newString.Append(input[i]);100
i++;101
}102
}103
}104
else { } //如果下个需要匹配的脏字超过了剩下了字符长度,则跳过当前脏字符.105

106
}107
}108
//如果没有键与当前字符匹配,则把当前字符加入输出字符串109
else if (key == KeyWordDictionary.AllKeys[KeyWordDictionary.Keys.Count - 1])110
{111
newString.Append(input[i]);112
i++;113
}114
}115
//catch (Exception e) { }116

117
}118
}119
}120
else newString.Append(input); //如果脏字字典为空,则返回原文121

122
return newString.ToString();123
}124

125
//根据传入的长度生成屏蔽符号126
private string ChangeTheWords(char input, int length)127
{128
StringBuilder newString = new StringBuilder();129

130
newString.Append(input);131

132
for (int i = 0; i < length; i++)133
{134
newString.Append("*");135
}136
return newString.ToString();137
}138
}139
}140



浙公网安备 33010602011771号