c#正则表达式
需求:从一个文件中,提取所有的邮件地址。正则表达式是用来进行文本(字符串)处理的技术,与语言无关。主要用来描述字符串特征。
特征:字符串中必须出现的内容,可能出现的内容,不能出现的内容三大特征。
观察字符串规律,根据规律总结特征,然后根据特定字符串的特征来编写正则表达式。
一、元字符
1、"." :表示 除\n(换行)之外的任意的单个字符。
2、"[]" :表示 其中的字符。只能选一个。
例:a[0123456789]b 表示ab之间只能出现0-9之中一个数字。 a[0-9a-z]b :a和b之间只能有1个字符。该字符只能在[0-9a-z]中选择。
a[^0-9a-z]b 除了[0-9a-z]以外的任意一个字符
3、“|” :表示 或的意思
例:z|food 由于|的优先级非常低,所以这个表达式代表 z或food。(z|f)ood。
4、“()” :改变运算优先级;提取组。二个作用
5、“*” :(0~∞)限定符。表示前面的表达式出现0次或多次。 a.*b (adafsfdsafsdafb正确)表示(ab,a.b,a...b,a.......b等).出现0次或多次
6、“+”:(1~∞)表示前面的表达式必须出现1次或多次。 a.+b (不匹配ab)
7、“?” (0,1)表示前面的表达式必须出现0次或1次;终止贪婪模式。正则表达式默认贪婪模式。
8、“{n}” :(n)表示前面的表达式必须出现n次。 a[0-9]{10}b
9、“{n,}” :(n~∞)限定前边的表达式至少出现n次,无上限。 1[a-z]{3,}2
10、“{n,m}”:(n~m)限定前边的表达式至少出现n次,最多出现m次。 a[0-9]{3,8}b
11、"^":表示字符串开头。 ^abc 必须以abc开头
12、“$” :表示字符串结尾。 xyz$ 必须以xyz结尾
13、“\d”等价于[0-9]
14、“\D”等 [^0-9]
15、“\s” 表示所有不可见字符,空白符
16、“\S” 除\s以外的所有字符
17、“\w” [0-9a-zA-Z]
18、“\W” 除\w以外的所有字符
19、“\b” 单词边界(断言,只判断,不匹配) "tommrow row, row rower" 要求找单词“row” 这时正则表达式就是“\brow\b”
任意单个字符 a[\s\S]b,a[\d\D]b,a[\w\W]b
.net中利用Regex类来处理正则表达式
Regex.IsMatch(str,pattern,RegexOptions);//判断是否匹配 默认情况下,如果在整个字符串中只要有一部分匹配给定的字符串则返回true.完全匹配,则必须在正则表达式两端加开始^和结束$
Regex.Match();//提取一个匹配
Regex.Matches();//提取所有匹配
Regex.Replace();//替换
Regex.Split();//分割
Regex.Escape(str);//转义
例子:
"z|food"
"^z|food$"
"^(z|food)$"
"(^z$)|(^food$)"
"^(z|f)ood$"
"^[0-9]{6}$"
"^\\d{6}$" :注意转义字符
@"^\d{6}$" :.net默认采用的是unicode字符匹配,所以中文的123456也是匹配的。
bool b = Regex.IsMatch(postcode, @"^\d{6}$", RegexOptions.ECMAScript); 指定RegexOptions.ECMAScript选项后,\d就只表示普通的数字,不包含全角的字符了
"^([0-9]{15}|[0-9]{17}[0-9xX])$" :身份证限定
"^[0-9]{15}$|^[0-9]{17}[0-9xX]$"
"^[0-9]{15}([0-9]{2}[0-9xX])?$"
@"^(\d{3,4}\-?\d{7,8}|\d{5})$"
//.出现在[]中,就表示一个普通的.可以不转义。
//-出现在[]中的第一个位置的时候可以不转义。
@"^[-a-zA-Z0-9._]+@[-0-9a-zA-Z]+(\.[a-zA-Z0-9]+){1,}$" :邮箱限定
@"^\w+@\w+(\.\w+){1,}$" :包含中文
bool b = Regex.IsMatch(email, @"^\w+@\w+(\.\w+){1,}$", RegexOptions.ECMAScript); 不包括中文了
"^a[x.]b$" :axb,a.b
二、字符串匹配、提取、替换
1、基本用法
Regex regex = new Regex(@"\d+",RegexOptions.ECMAScript); Match match = regex.Match(msg); while (match.Index!=0) { match = regex.Match(msg, match.Index + match.Value.Length); }
2、提取组 提取后的字符串中再进行分组。 用小括号来分组,利用左小括号“(”来数分组个数,和确定group下标。
//读取文件中的内容到字符串 string html = File.ReadAllText("提取Email.htm"); //创建正则表达式 MatchCollection matches = Regex.Matches(html, @"[-a-zA-Z0-9_.]+@([-a-zA-Z0-9]+((\.[a-zA-Z0-9]+){1,}))"); //输出 foreach (Match item in matches) { Console.WriteLine(item.Value + "===============" + item.Groups[1].Value + "=======" + item.Groups[2].Value);//groups[0]表示全部 } Console.WriteLine(matches.Count);
例子:获取路径中的文件名
string path = @"C:\Documents and Settings\Administrator\桌面\资料\讲课素材\正则表达式工具\Regulator20Bin\The Regulator 2.0\_FusionLic.dll"; Match match = Regex.Match(path, @".+\\(.+)"); Console.WriteLine(match.Groups[1].Value);
3、替换 分组
string msg = "我的生日是05/21/2010耶我的生日是03/11/2000耶我的生日是05/21/2010耶我的生日是05/21/2010耶"; //在替换的方法中,使用提取组。 注意在引用分组的时候是使用 $1、$2、..... msg = Regex.Replace(msg, @"(\d{2})/(\d{2})/(\d{4})", "$3-$1-$2");
string s = " hello 'welcome' to be'aut'iful 'China' fdsfds jfklds'jfdsk'lfjskl "; //如果就像表示一个普通的$1,则需要$$1 s = Regex.Replace(s, "'(.+?)'", "【$1】");
三、贪婪模式
string msg = "1111。11。111。111111。"; //正则表达式会尽可能多的找到匹配,这就是正则表达式的贪婪模式。 Match match = Regex.Match(msg, ".+"); //结果:"1111。11。111。111111。" //终止贪婪模式:"?" 具有终止贪婪模式的功能。 //当?出现在了另外一个限定符后的时候,表示终止贪婪模式。 //终止贪婪模式,表示尽可能少的去匹配,则只匹配一个。 Match match1 = Regex.Match(msg, ".+?"); //结果:"1"
例子1:
string msg = "1111。11。111。111111。 "; Match match = Regex.Match(msg, "(.+)(。)"); //"1111。11。111。111111。" Match match = Regex.Match(msg, ".+?。"); //"1111。"
四、反向引用
#region 反向引用 外引用分组用$1,内部用\1。合并重复字符 string str = "羊羊羊哥哥哥哥哥哥生生世世"; str = Regex.Replace(str,@"(.)\1+","$1"); MessageBox.Show(str); #endregion
五:用途
1、抓取网页图片 <img> 根据正则找img标签,然后利用WebClient对象DownloadFile方法
2、抓取网页邮箱信息
3、抓取网页职位信息