最近做了一个游戏聊天功能,其中有个过滤敏感字体的需求,其实这个功能很简单,完全前端去控制,
发送前把文本过滤一次,后端只转发就好。
一.重要性
正则表达式在编程中经常会用到如Web前端的合法输入检测【邮箱检测等】
如游戏聊天中的屏蔽字体等
二.学习
正则表达式规则,掌握一些常用的匹配规则,以下以为C#为例
1.匹配单个字符或单个单词
例如RegEx = small__Zhang ,则会匹配文本中出现的所有small__zhang
2.匹配单个任意字符"."
例如RegEx = small.,则会匹配诸如small. small1 smallX等
3.如果我们本身只想匹配"."呢,因为"."属于特殊字符,因为需要加个斜杠转义
例如Regex = small\.,则只会匹配small.
4.使用[]用以划定属于组内的字符的界限
例如RegEx = small[zx],则会匹配smallz或smallx
5.在[]中使用区间,中间用'-'连接
例如RegEx = small__zhang[0-9],则会匹配small__zhang0 ~ small__zhang9的所有字符
6.在[]中使用反义字符,用^开头
例如RegEx = small__zhang[^0-7],则会匹配除了small_-zhang0 ~ small__zhang7的其他small__zhangX字符
7.如想匹配'['或']'本身,则需要使用斜杠转义
8.元字符\d和\D
\d与[0-9]相同,\D与[^0-9]相同
9.元字符\w和\W
\w与[a-zA-Z0-9]相同,\W与[^a-zA-Z0-9]相同
10.元字符\s和\S
\s匹配所有单个空字符, \S匹配所有非空字符
11.匹配一个或多个用+
例如RegEx = a+,则匹配一个或多个a
12.邮箱检测
例如RegEx = [\w.]+@[\w.]+\.\w+
13.匹配零个或一个字符用?
例如RegEx = flowers?,则匹配所有的flower或flowers
14.匹配固定数据的字符,用{数字}
例如RegEx = 1[35]\d{9},则匹配13或14开头的手机号码
15.匹配区间以内数目的字符,用{最小数字,最大数字}
例如RegEx = \d{1, 3},则匹配1-3位数字
16贪婪匹配和惰性匹配
a.贪婪匹配会尽可能的匹配更多的字符,遇到匹配的不急着将匹配的字符保存到匹配集合中,而是继续扩展,直到无法继续匹配为止
b.惰性匹配会极可能的匹配可能少的字符,它从第一个字符开始找起,一旦符合条件,立刻保存到匹配集合中,然后继续进行查找
c.贪婪匹配描述和惰性匹配描述对比:
左边为贪婪匹配,右边为惰性匹配
? ??
+ +?
* *?
{n} {n}?
{n,m} {n,m}?
{n,} {n,}?
17贪婪匹配和惰性匹配对比
匹配文本 small__zhang is a <b> game developer </b> living in <b> GuangZhou </b>.
RegEx = <b>.*</b>,返回<b> game developer </b> living in <b> GuangZhou </b>
RegEx = <b>.*?</b>,返回<b> game developer </b> 与 <b> GuangZhou </b>
18.匹配边界使用\b
通常情况下以空格,段落首行,段落末尾,逗号,句号和'-'作为边界
例如RegEx = \bsmall,匹配small开头的字符
例如RegEx = \bzhang\b,匹配zhang这个字符串
19.匹配文本首,使用^
例如RegEx = ^\s*small__zhang,匹配文本的开头
20.匹配文本末尾,使用$
例如RegEx = small__zhang\s*$
21.子模式,使用"("和")"
例如RegEx = (<br\s*/?>){2,},则匹配诸如<br><br/><br />
22.或匹配,使用"|"
例如RegEx = <i>|<b>,则匹配<i>或<b>
23.子模式中使用或匹配
例如RegEx = (19|20)\d{2},则匹配19XX或20XX
24.嵌套子模式
例如RegEx = (19\d{2}|2000)-([1-9]|1[0-2]),月份可是1到9或者10到12
三.屏蔽关键字
public class SenesitiveWord
{
public static readonly Regex reg_word = null;
public static string[] GetDataBaseBlockWords()
{
List<string> dataBaseWords = DataMgr.sensitiveWordModel.GetAllWords();
string rets = dataBaseWords.ToArray();
return rets;
}
public static string GetPattern()
{
StringBuilder patt = new StringBuilder();
string s;
foreach(string word in GetDataBaseBlockWords())
{
if(word.Length == 0)
continue;
patt.AppendFormat("|{0}", word);
}
if(patt.Length > 0)
{
patt.remove(0, 1);
}
return patt.ToString();
}
private static Regex GetRegex()
{
if(reg_word == null)
{
reg_word = new Regex(GetPattern(), RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
}
return reg_word;
}
private bool HasBlockWords(string raw)
{
return GetRegex().Match(raw).Success;
}
private static string WordsFilter(string raw)
{
string ret = GetRegex().Replace(raw, "***");
return ret;
}
public static string ConvertToFilterWords(string raw)
{
string ret = raw;
if(HasBlockWords(raw))
{
ret = WordsFilter(raw);
}
return ret;
}
}
这样就可以过滤掉敏感词库中的字体了