关键字过滤
最近写了一个关键字过滤器,也就是脏字过滤,由于是新手,所以效率大家可能不敢恭维。
不过总算是实现了哈。
对于保存脏字的字典,用的是NameValueCollection,他的结构大概为下图:
一个键值组合,
一个键能对应多个值,
这就使得我们第一次
的匹配能减少很多次。
按照这个结构,我们把关键字的字典读取,每次增加关键字都会历遍Key组,如果相对应的Key已经存在,
则把值添加到对应Key的值组里面,如果不存在则创建新的Key来存放值。
下面是我的流程图:
然后是测试的效率:
最后是实现的代码,需要的兄弟可以用用,但不保证效率哈~
1using System;
2using System.Collections.Specialized;
3using System.Xml;
4using System.Text;
5using System.IO;
6
7namespace 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
2using System.Collections.Specialized;
3using System.Xml;
4using System.Text;
5using System.IO;
6
7namespace 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