//此为学习笔记如想要深入学习请去https://edu.csdn.net/learn/8573
一、正则表达式概述、元字符及其含义
正则表达式就是由普通字符以及特殊字符(称为元字符)组成的 “规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。也即是说正则表达式用来描述字符串的特征。用于字符串匹配、字符串提取、字符串替换。类似于通配符,比如*.Jpg,?ab,这里*、?是通配符,类似于元字符。又如like ‘张%’。
1、. 除\n(换行)以外的任意的单个字符。
a.b——表示ab之间有一个字符,且必须有一个,除了换行符
比如:aab、axb、a3b、a.b、 ab
a43b
2、[] 字符组:[]表示在字符组中罗列出来的字符中,任意取1个。
比如:
a[xyz]b——表示在xyz三个中必须取1个,如axb、ayb、azb都行
a[a-z]b——表示小写a到z之间必须取1个,如awb、azb、aab都行
a[a-zABXYZ]b——表示小写a到z或者ABXYZ之间必须取1个,如aAb
a[a-zA-Z0-9徐照兴]b——表示小写a到z、大写A到Z、0到9、徐、照、兴之间取1个
注意1:-出现在[]第一个不表示范围,如
a[-a-zX]b——表示在-、小写a到z和X之间必须取1个
注意2:.出现在字符组中表示一个普通的.,并不是一个元字符。
因此,a.b与a[.]b意思不一样。
a[.xyz]b 表示在.、x、y、z中必须取1个
注意3:a\.b——\.表示把.转义了,就表示1个普通字符,不是元字符了 a.b
3、| 表示“或”的意思。“或”的优先级最低。
a(x|y)b——表示a和b之间要么是x要么是y。axb ayb
z|food 表示匹配z或者匹配food
(z|f)ood——表示zood或food,通过()改变了优先级
() 表示“改变优先级”或者表示“提取组”。
4、[0-9]——表示0到9之间的数字任意取1个。[0-9]可以用[\d]表示,并不完全等价,主要在于默认情况下全角数字匹配\d,但是不匹配[0-9] 123 1 2 3
\d——表示0到9之间的数字 1 2 3
\D——除了0到9之间的数字字符的其他字符,也即是非数字字符
\w表示匹配字母或数字或下划线或汉字,即表示能组成单词的字符,即表示[a-zA-Z0-9_],汉字是指在Unicode模式下才可以有的。
\W除了[a-zA-Z0-9_]外的其他字符。
\s 表示所有不可见字符 如:空格 \r\n (\r回车符 、\n换行符)。
\S表示所有可见字符。
因此,以下几个都可以表示任意单个字符:[\s\S]、[\d\D]、[\w\W]。
二、限定符及其含义
1、a.*b *表示限定前面的表达式或元素出现0次或者多次。这里只能表示前面的.可出现0次或者多次,如果要表示前面的a. 出现0次或者多次,则要把a.括起来,即是(a.)*b, axa3a4b匹配(a.)*b b
即ab、a1b、axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxb、axxb都满足a.*b
2、a.+b +表示上一个元素出现一次或多次。至少得出现一次。
即ab 不满足。axb、axxxb、axyb都满足
3、a.?b ?表示上一个元素可出现0次或者1次。即ab、axb、aeb、a#b都满足a.?b,axcb 不满足。
?的另一个意思是终止贪婪模式。
4、
(1){ n }表示匹配上一个元素恰好 n 次,比如[0-9]{8}——表示0-9的任意数字出现8次。比如:
Oooooooo不满足、00000000满足、87979789满足
Zo{2}——表示Zoo,(Zo){2}就表示ZoZo
(2){ n ,} 匹配上一个元素至少 n 次。比如
[0-9]{4,}——表示0-9的任意数字至少出现4次,最多不限定
0009099999999满足 123098
(3){ n , m }匹配上一个元素至少 n 次,但不多于 m 次。
[0-9]{4,9}——表示0-9的任意数字至少出现4次,最多出现9次
98744满足
h[0-9]{3,5}l——表示hl之间要有数字0到9的字符,且至少出现3次,最多出现5次
h12l、hl不满足
h123l、h34563l都满足
5、^hl——^表示开头,这个表示以hl开头
123adafhlkkj不满足
hl1234jh满足
^王..——表示姓王的且为三个字的名字,因为.表示除换行符外的单个字符
6、oo$——$表示结尾,这个就表示以oo结尾的字符串
Zoo、yahoo、too满足
注意:^出现在[]里不表示开头的意思,表示非的意思
a[^zxy]b——这个表示ab之间不能出现zxy三个字符,其他任意1个字符都行
如,ab不满足,因为ab之间没有任何字符
7、\b——匹配单词边界 welcome you
\bhello\b yhello1
三、验证数字、邮政编码、手机号等常见数字验证
在C#中,要使用正则表达式类,主要用RegEx类,并需要引入命名空间如下:
using System.Text.RegularExpressions;
RegEx类常用的方法——IsMatch
语法格式如下
public static bool IsMatch(string input, string pattern);
input:要搜索匹配项的字符串
pattern:要匹配的正则表达式模式
返回值:如果正则表达式找到匹配项,则为true,否则为false
#region 例1验证输入的字符是否为数字。
//Console.WriteLine("请输入数字:");
//string num = Console.ReadLine();
//Console.WriteLine(Regex.IsMatch(num, @"^[0-9]+$"));//@为取消\的转义,当然也可以写成"^\\d$",即写两个\
//Console.WriteLine(Regex.IsMatch(num, @"^\d+$"));
//Console.ReadKey();
#endregion
#region 例2 体会.Net默认使用的是Unicode匹配模式
//string msg = "123";//123 123
//bool b = Regex.IsMatch(msg, @"\d+", RegexOptions.ECMAScript);//结果为false,后面那个参数表示匹配ASCII字符
bool b = Regex.IsMatch(msg, @"\d+");//结果为true
bool b = Regex.IsMatch(msg, @"[0-9]+"); //这个可以准确判断是ASCII字符123,不包含unicode字符123,其实就是在输入法中使用“全角”输出123,这个结果为false
//Console.WriteLine(b);
//string msg2 = "xzx135_7607jift__徐照兴云课堂";
bool b2 = Regex.IsMatch(msg, @"^\w+$");//这个结果为true,因为默认匹配的Unicode字符,那么\w可以表示汉字
//bool b2 = Regex.IsMatch(msg2, @"^\w+$", RegexOptions.ECMAScript);//后面参数表示匹配ASCII字符,不匹配Unicode字符,即不包括汉字,所以这个结果false
//Console.WriteLine(b2);
//Console.ReadKey();
#endregion
#region 例3:验证是否是合法的手机号。
//Console.WriteLine("请输入手机号:");
//string num = Console.ReadLine();
//Console.WriteLine(Regex.IsMatch(num, @"^\d{11}$"));//@为取消\的转义,当然也可以写成"^\\d{11}$",即写两个\
//Console.ReadKey();
#endregion
#region 例5:判断一个字符串是不是身份证号码。
1.长度为15位或者18位的字符串,首位不能是0。
2.如果是15位,则全部是数字。
3.如果是18位,则前17位都是数字,末位可能是数字也可能是X。
//while (true)
//{
// Console.WriteLine("输入身份证号:");
// string idNo = Console.ReadLine();
// Console.WriteLine(Regex.IsMatch(idNo, @"(^[1-9][0-9]{14}$)|(^[1-9][0-9]{16}[0-9Xx]$)"));
//}
#endregion
#region 例6:判断字符串是否为正确的国内电话号码,不考虑分机。
010-8888888或010-88888880或010xxxxxxx
0335-8888888或0335-88888888(区号-电话号)03358888888
10086、10010、95595、95599、95588(5位)
13888888888(11位都是数字)
//while (true)
//{
// Console.WriteLine("请输入电话号码:");
// string number = Console.ReadLine();
// //\d{3,4}-?\d{7,8}这个也包括\d{11}这种情况
// //\d{5}
// bool b = Regex.IsMatch(number, @"^(\d{3,4}-?\d{7,8}|\d{5})$");
// Console.WriteLine(b);
//}
#endregion
#region 例7:判断是否是合法的日期格式“2018-04-08”。
//while (true)
//{
// Console.WriteLine("输入日期:");
// string date = Console.ReadLine();
// //bool b = Regex.IsMatch(date, @"^[0-9]{4}-[0-9]{2}-[0-9]{2}$");
// //限制月份只能是1-12月
// //01-9
// //0[1-9]
// //1[0-2]
// //bool b = Regex.IsMatch(date, @"^[0-9]{4}-(0?[1-9]|1[0-2])-[0-9]{2}$");
// //再限定日只能在1-31之间
// bool b = Regex.IsMatch(date, @"^[0-9]{4}-(0?[1-9]|1[0-2])-((0?[1-9])|((1|2)[0-9])|30|31)$");
// Console.WriteLine(b);
//}
#endregion
#region 练习验证一个数字表达式是否为两位小数。
//while (true)
//{
// Console.WriteLine("输入一个数字表达式:");
// string strnum = Console.ReadLine();
// bool b = Regex.IsMatch(strnum, @"^[0-9]+(.[0-9]{2})$");
// Console.WriteLine(b);
//}
#endregion
#region 例8:验证是否为合法的邮件地址
表示用户名部分可以是-、0-9、a-z、A-Z、_、.,可以出现一次或多次,然后是@,域名部分是a-z、A-Z、0-9出现一次或多次,然后是(.再后面是a-z、A-Z出现1次或多次),整个括弧里的可出现1-2次
//while (true)
//{
// Console.WriteLine("请输入一个Email地址:");
// string email = Console.ReadLine();
// Console.WriteLine(Regex.IsMatch(email, @"^[-0-9a-zA-Z_.]+@[a-zA-Z0-9]+(.[a-zA-Z]+){1,2}$"));
//}
\w + ([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
#endregion
#region 例9:判断是否是合法的url地址,http://www.test.com/a.htm?id=3&name=aaa、ftp://127.0.0.1/1.txt。字符串序列://字符串序列。http、https、ftp、file、thunder、ed2k
//while (true)
//{
// Console.WriteLine("输入一个url:");
// string url = Console.ReadLine();
// //http://.....................
// bool b = Regex.IsMatch(url, @"^[a-zA-Z0-9]+://.+$");
// Console.WriteLine(b);
//}
http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?
#endregion
#region 例10:验证IP地址,4段用.分割的最多三位数字。
//while (true)
//{
// Console.WriteLine("请输入ip:");
// string ip = Console.ReadLine();
// //bool b = Regex.IsMatch(ip, @"^([0-9]{1,3}\.){3}[0-9]{1,3}$");//这种方式只匹配4段用.分割的数字
// //通过下面两行可以准确匹配IP地址的范围
// string num = @"(25[0-5]|2[0-4]\d|[1]\d{2}|[1-9]?\d)";
// //string num = "(25[0-5]|2[0-4]\\d|[1]\\d{2}|[1-9]?\\d)";//说明字符串中\\表示\,所以\\d表示成正则\d
// bool b = Regex.IsMatch(ip, ("^" + num + @"\." + num + @"\." + num + @"\." + num + "$"));
// //bool b = Regex.IsMatch(ip, ("^" + num + "\\." + num + "\\." + num + "\\." + num + "$"));//字符串\\.表示成正则的\.,而\.表示取消.的元字符含义
// Console.WriteLine(b);
//}
#region 例11:阅读以下程序程序片段,写出主要含义,并注意区分
//==1. 含义:只要字符串中含有z或food就匹配,比如“xzx”匹配,“什么样的food最好吃?”匹配==
//while (true)
//{
// Console.WriteLine("请输入一个字符串:");
// string msg = Console.ReadLine();
// Console.WriteLine(Regex.IsMatch(msg, "z|food"));
//}
//==2. 含义:只要字符串中含有zood或food就匹配==
//while (true)
//{
// Console.WriteLine("请输入一个字符串:");
// string msg = Console.ReadLine();
// Console.WriteLine(Regex.IsMatch(msg, "(z|f)ood"));
//}
//==3. 含义:要么是以z开头的,要么是以food结尾的都认为是true==
//while (true)
//{
// Console.WriteLine("请输入一个字符串:");
// string msg = Console.ReadLine();
// Console.WriteLine(Regex.IsMatch(msg, "^z|food$"));//匹配以z开头或以food结尾的
//}
//==4. 含义:要么匹配字符串z,要么匹配字符串food,由于前面加了^,后面加了$,则表示完整匹配,又加了(),则表示完整匹配()里面的,而()里为z或food==
//while (true)
//{
// Console.WriteLine("请输入一个字符串:");
// string msg = Console.ReadLine();
// Console.WriteLine(Regex.IsMatch(msg, "^(z|food)$"));
//}
#endregion
#region 例12:验证输入的是否为中文汉字
//while (true)
//{
// Console.WriteLine("请输入中文字符串:");
// string msg = Console.ReadLine();
// Console.WriteLine(Regex.IsMatch(msg, "^[\u4e00-\u9fa5]{1,}$"));
// //\u4e00、\u9fa5分别表示Unicode表中的汉字的头和尾
//}
#endregion
#region 例13:使用正则表达式拆分字符串
//string msg = "徐照兴0791-87656765张三0794-87676567李四021-98765678王五0109876567";
//string[] strs=Regex.Split(msg, @"\d{3,4}-?\d+");
//foreach (string s in strs)
//{
// Console.WriteLine(s);
//}
//Console.ReadKey();
#endregion
===Regex.Matches提取字符串中所有匹配正则的字符串====
#region 例14:提取字符串中的所有数字
//string msg = "Hello,大家好!欢迎大家进入徐照兴.NET云课堂,于2017年11月26日开始上线,于2018年1月12日完成ASP.NET就业实例教程全部课程。恩,9494.要休息了!886.";
字符串提取正则一般不加^ 和 $,加上这两个msg表示要完整匹配正则表达是,否则就表示msg中有部分匹配正则表达式即可
====Regex.Match只能提取第一个匹配字符串=========
使用\d + 而不是\d,\d只能提取单个的数字字符,当然\d用[0-9]代替可行
// Match match = Regex.Match(msg, "[0-9]+");
//Console.WriteLine(match.Value);
===Regex.Matches提取字符串中所有匹配正则的字符串====
//MatchCollection matches = Regex.Matches(msg, "[0-9]+");
//foreach (Match item in matches)
//{
// Console.WriteLine(item.Value);
//}
//Console.ReadKey();
#endregion
#region 例15:从Email中提取出用户名和域名,比如从xuzhaoxing@163.com中提取出xuzhaoxing和163.com。
//while (true)
//{
// Console.WriteLine("请输入Email:");
// string email = Console.ReadLine();
// Match match = Regex.Match(email, @"(.+)@(.+)");
// Console.WriteLine("用户名:{0},域名:{1}", match.Groups[1].Value, match.Groups[2].Value);
//}
xzx@jift.edu.cn
#endregion
#region 例16:提取html网页中的邮箱地址
//string html = File.ReadAllText("1.htm");
从字符串中提取子字符串。
如果想要对已经匹配的字符串再进行分组提取,就用到了“提取组”的功能
通过添加()就能实现提取组。
在正则表达式中只要出现了()就表示进行了分组。小括号既有改变优先级的作用又具有提取组的功能。提取组:提取每个Email的用户名与域名。用()提取组。
//MatchCollection matches = Regex.Matches(html, @"([-a-zA-Z_0-9.]+)@([-a-zA-Z0-9_]+(\.[a-zA-Z]+)+)");
//foreach (Match item in matches)
//{
// //item.Value表示本次提取到的字符串
// //item.Groups集合中存储的就是所有的分组信息。
// //item.Groups[0].Value与item.Value是等价的都表示本次提取到的完整的字符串,表示整个邮箱字符串,而item.Groups[1].Value则表示第一组的字符串。
// //Console.WriteLine(item.Value);
// Console.WriteLine("第0组:{0}", item.Groups[0].Value);
// Console.WriteLine("第1组:{0}", item.Groups[1].Value);
// Console.WriteLine("第2组:{0}", item.Groups[2].Value);
// Console.WriteLine("===============================================");
//}
//Console.WriteLine("ok");
//Console.WriteLine(matches.Count);
//Console.ReadKey();
#endregion
#region 例17:“192.168.10.5[port=21,type=ftp]”,这个字符串表示IP地址为192.168.10.5的服务器的21端口提供的是ftp服务,其中如果“,type=ftp”部分被省略,则默认为http服务。请用程序解析此字符串,然后打印出“IP地址为***的服务器的***端口提供的服务为***”
string msg = "192.168.10.5[port=21,type=ftp]";
//string msg = "192.168.10.5[port=21]";
下面.+实际能把非IP形式字符串也能匹配出来
//Match match = Regex.Match(msg, @"(.+)\[port=([0-9]{2,5})(,type=(.+))?\]");
//Console.WriteLine("ip:{0}", match.Groups[1].Value);
//Console.WriteLine("port:{0}", match.Groups[2].Value);
//Console.WriteLine("services:{0}", match.Groups[4].Value.Length == 0 ? "http" : match.Groups[4].Value);
//Console.ReadKey();
#endregion
#region 练习:从“June 26 , 1951 ”中提取出月份June、26、1951来。@"^([a-zA-Z]+)\s+(\d{1,2})\s*,\s*(\d{4})\s*$"进行匹配。月份和日之间是必须要有空格分割的,所以使用空白符号“\s”匹配所有的空白字符,此处的空格是必须有的,所以使用“+”标识为匹配1至多个空格。之后的“,”与年份之间的空格是可有可无的,所以使用“*”表示为匹配0至多个
//======第一种写法:========
//string date1 = "Auguat 24 , 1982 ";
//Match match = Regex.Match(date1, @"([a-zA-Z]+)\s+([0-9]{2})\s*,\s*([0-9]{4})\s*");//这种方法匹配一个完整的
//for (int i = 0; i < match.Groups.Count; i++)
//{
// Console.WriteLine(match.Groups[i].Value);
//}
//Console.ReadKey();
====第2种写法:===========
//string date2 = "Auguat 24 , 1982 ";
//MatchCollection matches = Regex.Matches(date2, "[a-zA-Z0-9]+"); //这种匹配到多个
//foreach (Match item in matches)
//{
// Console.WriteLine(item.Value);
//}
//Console.ReadKey()
#region 贪婪模式 例18:分析下面程序输出结果
贪婪模式
//1111。11。111。111111。
//string msg = "1111。11。111。111111。";
.+,默认按照贪婪模式来匹配,尽可能多的去匹配。
//Match match = Regex.Match(msg, ".+");
//Console.WriteLine(match.Value);//输出结果为msg字符串的全部
//Console.ReadKey();
#endregion
#region 终止贪婪模式 例19:分析下面程序输出结果
1111。11。111。111111。
//string msg = "1111。11。111。111111。";
.+,默认按照贪婪模式来匹配,尽可能多的去匹配。
当在“限定符”后使用?的时候,表示终止贪婪模式
当终止贪婪模式之后,会尽可能少的匹配。
//Match match = Regex.Match(msg, ".+?");
//Console.WriteLine(match.Value);//结果只有1
//Console.ReadKey();
#endregion
#region 练习:分析下面程序输出结果
//string msg = "1111。11。111。111111。";
//Match match1 = Regex.Match(msg, ".+");
//Console.WriteLine(match1.Value);//输出msg字符串全部
//Match match2 = Regex.Match(msg, ".+。");
//Console.WriteLine(match2.Value);//输出msg字符串全部
//Match match3 = Regex.Match(msg, ".+?。");
//Console.WriteLine(match2.Value);//输出1111。
//string str = "abbb";
//Match match4 = Regex.Match(str, "ab*?");
//Console.WriteLine(match4.Value);//结果为a
//Match match5 = Regex.Match(str, "ab*");
//Console.WriteLine(match5.Value);//结果为abbb
//Console.ReadKey();
#endregion
#region 例20:提取给定字符串中的所有姓名
//string msg = "大家好。我们是.NET云课堂。我是徐照兴。我是刘武。我是杨涛。我是魏娟。我是刘捷。我是Mary。哈哈";
//MatchCollection matches = Regex.Matches(msg, "我是(.+?)。");
//foreach (Match item in matches)
//{
// Console.WriteLine(item.Groups[1].Value);
//}
//Console.ReadKey();
#endregion
通过WebClient来提取Email地址
#region 例21:通过WebClient来提取Email地址
//WebClient client = new WebClient();
string html = client.DownloadString("1.htm");
//string html = client.DownloadString("http://tieba.baidu.com/p/496274307");
从html字符串中提取邮件地址
//MatchCollection matches = Regex.Matches(html, @"[-a-zA-Z0-9_.]+@[-a-zA-Z0-9]+(\.[a-zA-Z]+){1,2}");
//foreach (Match item in matches)
//{
// Console.WriteLine(item.Value);
//}
//Console.WriteLine("共{0}个邮箱地址。", matches.Count);
//Console.ReadKey();
#endregion
#region 例22:提取网页的图片
//WebClient wb = new WebClient();
1.下载html
//string html = wb.DownloadString("http://www.jift.edu.cn/");
2提取里面的<img/>标签
通过网页源代码分析<img标签,写对应的正则表达式
< img src = "images/IMG_1969.jpg" >
< img src = "images/hongge.jpg" >
< img src = "img/kstd2.png" alt = "" >
//MatchCollection matches = Regex.Matches(html, @"<\s*img\s+src=""(.+?)"".*>", RegexOptions.IgnoreCase);
3.通过“提取组”获取img的src属性
//foreach (Match item in matches)
//{
// //Console.WriteLine(item.Groups[1].Value);
// string pathImg = "http://www.jift.edu.cn/" + item.Groups[1].Value;
// //4.下载图片 通过拼接路径实现下载图片
// wb.DownloadFile(pathImg, @"d:\downpic\" + System.DateTime.Now.ToFileTime() + ".jpg");
//}
//Console.WriteLine("ok");
//Console.ReadKey();
#endregion
#region 例23:提取网页中的超链接
// WebClient wb = new WebClient();
// string html = wb.DownloadString("http://sxy.jift.edu.cn/");
// // <a href="info/1148/1198.htm" target="_blank"><img src="/__local/A/61/16/578CD30FB340ECE18A9BE19F9F4_FDBA8395_2B209.png" align="left" width="100" height="75" border="0" style="padding:2px"></a>
< a href = "info/1148/1209.htm" target = "_blank" title = "商学院2017年暑期教职工评估培训" > 商学院2017年暑期教职工评估培训 </ a >
// MatchCollection matches = Regex.Matches(html, @"<\s*a\s*href="".+?"".*>.+?</a>", RegexOptions.IgnoreCase);
// foreach (Match item in matches)
// {
// Console.WriteLine(item.Value);
// }
// Console.ReadKey();
#endregion
#region 注意
//string s = "\"";//前面没有@符号,\"表示"
//Console.WriteLine(s);
//Console.ReadKey();
//string s = @"""";//加了@,两个"表示一个"
//Console.WriteLine(s);
//Console.ReadKey();
#endregion
如果匹配的正则字符串中有分组,即有(),可以在替换字符串中用$number来进行引用替换。从左往右,第1对()里的内容用$1引用,第2对()里的内容用$2引用,依次类推。$0表示正则匹配到的完整字符串。
#region 例24:字符串替换
//string msg = "你aaa好aa哈哈a你";
//msg = msg.Replace("a", "A");//这个是字符串Replace函数
//Console.WriteLine(msg);
//Console.ReadKey();
//string msg = "你aaa好aa哈哈a你";
//msg = Regex.Replace(msg, "a+", "A");
//Console.WriteLine(msg);
//Console.ReadKey();
#endregion
#region 例25:引用替换1。将hello ‘welcome’ to ‘China’替换成 hello 【welcome】 to 【China】
//string msg = "hello 'welcome' to 'China'";
//msg = Regex.Replace(msg, "'(.+?)'", "【$1】");
//Console.WriteLine(msg);
//Console.ReadKey();
#endregion
#region 例26:引用替换2。隐藏手机号码中间4位数
//string msg = "徐照兴13576071646张三15878987656李四13876788990高艳红15087655678";
//msg = Regex.Replace(msg, @"([0-9]{3})[0-9]{4}([0-9]{4})", "$1****$2");
//Console.WriteLine(msg);
//Console.ReadKey();
#endregion
#region 引用替换练习1:将一段文本中的MM/DD/YYYY格式的日期转换为YYYY-MM-DD格式 ,比如“我的生日是08/24/1981耶”转换为“我的生日是1981-08-24耶”。
//string msg = "我的生日是08/24/1981耶我的生日是08/24/1981耶";
//msg = Regex.Replace(msg, @"(\d{2})/(\d{2})/(\d{4})", "$3-$1-$2", RegexOptions.ECMAScript);
//Console.WriteLine(msg);
//Console.ReadKey();
#endregion
#region 引用替换练习2:给一段文本中匹配到的url添加超链接,比如把http://study.163.com/替换为<a href="http://study.163.com/"> http://study.163.com/</a>。
//string msg = "给一段文本中匹配到的url添加超链接,比如把http://study.163.com/替换网易云课堂搜索徐照兴,哈哈http://www.google.com";
//msg = Regex.Replace(msg, @"[a-zA-Z0-9]+://[-a-zA-Z0-9.?&=#%\/_]+", "<a href=\"$0\">$0</a>");
//Console.WriteLine(msg);
//Console.ReadKey();
#endregion
如果匹配的正则字符串中有分组,即有(),可以在该正则中通过\number来反向引用()中的分组字符串。从左往右,第1对()里的内容用\1引用,第2对()里的内容用\2引用,依次类推。
比如:
((a)x(b))\1\2\3 匹配axbaxbab ,而$1表示替换的分组
#region 例27:反向引用——叠词处理
//string msg = "你们喜欢徐徐徐徐徐照照照照照兴兴兴兴兴兴兴兴兴兴兴课堂吗?";
//msg = Regex.Replace(msg, @"(.)\1+", "$1");//\1表示内部引用分组——反向引用
((a)x(b))\1\2\3 匹配axbaxbab $1表示替换的分组
//Console.WriteLine(msg);
//Console.ReadKey();
#endregion
#region 例28:提取带有重复字母的单词
//string txt = File.ReadAllText("1.txt", Encoding.Default);
//MatchCollection matches = Regex.Matches(txt, @"[a-zA-Z]*([a-zA-Z])\1+[a-zA-Z]*");
//foreach (Match item in matches)
//{
// Console.WriteLine(item.Value);
//}
//Console.ReadKey();
#endregion
#region 例29:提取叠词
//string msg = File.ReadAllText("2.txt", Encoding.Default);
AABB
//MatchCollection matches = Regex.Matches(msg, @"(.)\1(.)\2");
//foreach (Match item in matches)
//{
// Console.WriteLine(item.Value);
//}
//Console.ReadKey();
#endregion
#region 例30:单词边界\b 的使用.单词row替换为line
//string msg = "The day after tomorrow is my wedding day.The row we are looking for is row number 10.";
msg = msg.Replace("row", "line");
//msg = Regex.Replace(msg, @"\brow\b", "line");
//Console.WriteLine(msg);
//Console.ReadKey();
#endregion
#region 例31:请提取出3个字母的单词
//string msg = "Hi,how are you?Welcome to our country!";
//MatchCollection matches = Regex.Matches(msg, @"\b[a-z]{3}\b", RegexOptions.IgnoreCase);
//foreach (Match item in matches)
//{
// Console.WriteLine(item.Value);
//}
//Console.ReadKey();
#endregion
#region 例32:环视的理解。提取msg字符串中连续3个#的字符串
//string msg = "# ## ### #### ## ### # ###.";
MatchCollection matches = Regex.Matches(msg, @"\b###\b");//匹配结果为空
(?<= )表示环视的逆序,即是判断左边是什么,(?<!= ) 判断左边不是什么
(?= )表示环视的顺序,即是判断右边是什么, (?!= ) 判断右边不是什么
//MatchCollection matches = Regex.Matches(msg, @"(?<= )###(?= |\.)");//表示###左边是空格,右边也是一个空格或.
//foreach (Match item in matches)
//{
// Console.WriteLine(item.Value);
//}
//Console.ReadKey();
#endregion
敏感词汇过滤
//首先建议敏感词汇库保存本地1.txt
安定片={MOD}
罢餐={MOD}
罢工={MOD}
罢食={MOD}
百家乐={MOD}
百家乐={MOD}
办理商业发票={BANNED}
办理文凭={BANNED}
办理无抵押贷款={BANNED}
办理证件={MOD}
办证={MOD}
办证刻章发票={BANNED}
棒子={MOD}
冰毒={BANNED}
博彩={BANNED}
博翔团队={BANNED}
步.{0,2}枪={BANNED}
彩票机={BANNED}
彩票奖券网={BANNED}
厂家={MOD}
成人导航={BANNED}
成人电影={BANNED}
成人交友={BANNED}
成人论坛={BANNED}
成人片={BANNED}
成人频道={BANNED}
成人贴图={BANNED}
成人网={BANNED}
成人文学={BANNED}
成人午夜场={BANNED}
成人小说={BANNED}
出售={MOD}
出售假币={BANNED}
出售手枪={BANNED}
出售银行卡={BANNED}
传真群发={BANNED}
春药={BANNED}
网络推广={MOD}
网络营销={MOD}
网上办证={BANNED}
网上订机票={BANNED}
网赚={MOD}
卫星接收器={MOD}
未删节={BANNED}
文凭={MOD}
下半身={MOD}
private void button1_Click(object sender, EventArgs e)
{
//用来存储需要审核的关键词
StringBuilder sbMode = new StringBuilder();
//用来存储绝对禁止的关键词
StringBuilder sbBanned = new StringBuilder();
string[] lines = File.ReadAllLines("1.txt", Encoding.Default);
for (int i = 0; i < lines.Length; i++)
{
//lines[i];
string[] parts = lines[i].Split('=');
if (parts[1] == "{MOD}")
{
sbMode.AppendFormat("{0}|", parts[0]);
}
else if (parts[1] == "{BANNED}")
{
sbBanned.AppendFormat("{0}|", parts[0]);
}
}
sbMode.Remove(sbMode.Length - 1, 1);
sbBanned.Remove(sbBanned.Length - 1, 1);
string userInput = textBox1.Text.Trim();
//验证是否有禁止发帖的关键词
//"fdsafdsfdsfdsa" "a|b|c"
if (Regex.IsMatch(userInput, sbBanned.ToString()))
{
MessageBox.Show("禁止发帖!");
}
else if (Regex.IsMatch(userInput, sbMode.ToString()))
{
MessageBox.Show("需要审核!");
}
else
{
MessageBox.Show("可以发帖!");
}
}