正则表达式总结(一)
字符串和正则表达式
复习前面知识
1、引入:在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。
Windows/Dos下用于文件查找的通配符(wildcard)
2、简单例子:
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System.Text.RegularExpressions;
2 namespace ConsoleApplication1
3 {
4 class Program
5 {
6 static void Main(string[] args)
7 {
8 string Pattern = @"hi";
9 string s = @"hi Hi THIS hI HI chAINA";
10 MatchCollection Matches = Regex.Matches(s, Pattern,RegexOptions.IgnoreCase);
11 foreach (Match NextMatch in Matches)
12 {
13 Console.WriteLine(NextMatch.ToString());
14 }
15 }
16 }
17 }
结果:
RegexOptions枚举选项:
查看MSDN
3 主要得特定字符或转义序列
1)元字符
常用元字符:
\S 任何不是空白得字符
\B 不是字边界得位置
Eg:
i.ation 结果为isation iztion
\ba\w*\b匹配以字母a开头的单词,然后是任意数量的字母或数字(\w*),最后是单词结束处(\b)。
\b\w{6}\b 匹配刚好6个字母/数字的单词。
\d+匹配1个或更多连续的数字。
\ba\S*ion\b ----------表示以a开头,中间为任意个不是空白的字符,以ion结尾
元字符^(和数字6在同一个键位上的符号)和$都匹配一个位置,这和\b有点类似。^匹配你要用来查找的字符串的开头,$匹配结尾。这两个代码在验证输入的内容时非常有用,比如一个网站如果要求你填写的QQ号必须为5位到12位数字时,可以使用:^\d{5,12}$。
2)字符转义
如果你想查找元字符本身的话就必须使用字符转义
C:\\Windows匹配C:\Windows
需要转义的还有:
( ) * + . [ ] ? |
C#中要想输出. 不需要转义
规则:C#中写正则表达式string Pattern = @"unibetter\$com";引号里面得东东如果要输出上面的那些特殊得字符的话,就必须在该字符得前面加上\ 然后前面的@不能掉
3)重复
Eg:
ra*t 结果为rt rat raat raaat
ra+t 结果为rat raat raaat
ra?t 结果为rt rat
Windows\d+匹配Windows后面跟1个或更多数字
^\w+匹配一行的第一个单词
4)字符类
指定一个范围:
像[aeiou]就匹配任何一个英文元音字母,[.?!]匹配标点符号(.或?或!),像[0-9]代表的含意与\d就是完全一致的:一位数字;同理[a-z0-9A-Z_]也完全等同于\w
分析:\(?0\d{2}[) -]?\d{8}
先是一个转义字符\
然后是( 后面是?表示( 可以出现0次或1次
再是一个0 然后后面是接两个数字 然后[) -]? 表示)或-可以出现一次或0次
最后就是接八个数字
可以出现得情形:(010)33344432
022-34566666
03292929399 (03292929399 032)92929399
(032-92929399
5)分支条件
0\d{2}-\d{8}|0\d{3}-\d{7}这个表达式能匹配两种以连字号分隔的电话号码:一种是三位区号,8位本地号(如010-12345678),一种是4位区号,7位本地号(0376-2233445)。
\(0\d{2}\)[- ]?\d{8}|0\d{2}[- ]?\d{8}这个表达式匹配3位区号的电话号码,其中区号可以用小括号括起来,也可以不用,区号与本地号间可以用连字号或空格间隔,也可以没有间隔
6)分组
如果想要重复多个字符又可以用小括号来指定子表达式(也叫做分组)
(\d{1,3}\.){3}\d{1,3}是一个简单的IP地址匹配表达式。要理解这个表达式,请按下列顺序分析它:\d{1,3}匹配1到3位的数字,(\d{1,3}\.){3}匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,最后再加上一个一到三位的数字(\d{1,3})。
122.2.2.123
7)反义
8)零宽断言
(?=exp)也叫零宽度正预测先行断言
\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc
(?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading
零宽度负预测先行断言(?!exp),断言此位置的后面不能匹配表达式exp
例如:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字
(?<!exp),零宽度正回顾后发断言来断言此位置的前面不能匹配表达式exp:(?<![a-z])\d{7}匹配前面不是小写字母的七位数字
9.)贪婪与懒惰
a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。
a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab
*为什么第一个匹配是aab(第一到第三个字符)而不是ab(第二到第三个字符)?简单地说,因为正则表达式有另一条规则,比懒惰/贪婪规则的优先级更高:最先开始的匹配拥有最高的优先权
三、正则在C#中的运用
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System.Text.RegularExpressions;
2 class Program
3 {
4 static void Main(string[] args)
5 {
6 //Program.matchExpressions("Adsdsds323232");
7 //Program.matchAndReturn("2aaasss3");
8 Program.matchAndReturn("<a href='www.baidu.com'>你好的速度撒</a><a href='www.baidu.com'>东东</a>");
9 //Program.replaceWord("bbbddsdsads,fdfdddddaaaa");
10 //Program.splitWord("192.168.1.1");
11 }
12 //匹配是否存在
13 private static void matchExpressions(string strString)
14 {
15 if (Regex.IsMatch(strString, @"\ba", RegexOptions.IgnoreCase))
16 Console.WriteLine("YES");
17 else
18 Console.WriteLine("NO");
19 }
20 //匹配,并且返回匹配值
21 private static void matchAndReturn(string strString)
22 {
23 // MatchCollection maths = Regex.Matches(strString, @"\d+");
24 MatchCollection maths = Regex.Matches(strString, @"<a\s+href=(?<url>.+?)>(?<content>.+?)</a>", RegexOptions.IgnoreCase);
25 //不区分大小写的匹配 并且匹配多行,编译(表示你的正则表达式是否要编译,就类比我们数据库中的存储结构和一般的查询语句的关系.如果你的正则表达式只用一次,那么你编译就没有什么意义,如果很常用,那么编译后,以后的匹配就快些.)
26 //MatchCollection maths = new Regex(strString, @"<a\s+href=(?<url>.+?)>(?<content>.+?)</a>", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Complied);
27 if (maths != null)
28 {
29 foreach (Match mc in maths)
30 {
31 string content = mc.Groups["content"].Value;
32 Console.WriteLine(content);
33 //Console.WriteLine(mc.ToString());
34 }
35 }
36 else
37 Console.WriteLine("字符串中不包含匹配的项");
38 }
39 //替换
40 private static void replaceWord(string strString)
41 {
42 Regex regex = new Regex("a");
43 string result = regex.Replace(strString, "");//b替代a
44 Console.WriteLine(result);
45 }
46 //分割
47 private static void splitWord(string strString)
48 {
49 Regex regex = new Regex(@"\.");
50 string[] result = regex.Split(strString);
51 foreach (var a in result)
52 {
53 Console.WriteLine(a);
54 }
55 }
56 }