【转】C#正则表达式教程和示例

有一段时间,正则表达式学习很火热很潮流,当时在CSDN一天就能看到好几个正则表达式的帖子,那段时间借助论坛以及Wrox Press出版的《C#字符串和正则表达式参考手册》学习了一些基础的知识,同时也为我在CSDN大概赚了1000分,今天想起来,去找《C#字符串和正则表达式参考手册》时,已经不知所踪了。现在用到正则的时候也比较少,把以前的笔记等整理一下,以志不忘。

(1)“@”符号
“@”虽然并非C#正则表达式的“成员”,但是它经常与C#正则表达式出双入对。“@”表示,跟在它后面的字符串是个“逐字字符串”,不是很好理解,举个例子,以下两个声明是等效的:
string x="D://My Huang//My Doc";
string y = @"D:/My Huang/My Doc";
事实上,如果按如下声明,C#将会报错,因为“/”在C#中用于实现转义,如“/n”换行:
string x = "D:/My Huang/My Doc";

(2)基本的语法字符。
/d  0-9的数字
/D  /d的补集(以所以字符为全集,下同),即所有非数字的字符
/w  单词字符,指大小写字母、0-9的数字、下划线
/W  /w的补集
/s  空白字符,包括换行符/n、回车符/r、制表符/t、垂直制表符/v、换页符/f
/S  /s的补集
.  除换行符/n外的任意字符
[…]  匹配[]内所列出的所有字符
[^…]  匹配非[]内所列出的字符
下面提供一些简单的示例:

 1 string i = "/n";
 2 string m = "3";
 3 Regex r = new Regex(@"/D");
 4 //同Regex r = new Regex("//D");
 5 //r.IsMatch(i)结果:true
 6 //r.IsMatch(m)结果:false
 7
 8 string i = "%";
 9 string m = "3";
10 Regex r = new Regex("[a-z0-9]");
11 //匹配小写字母或数字字符
12 //r.IsMatch(i)结果:false
13 //r.IsMatch(m)结果:true

(3)定位字符
“定位字符”所代表的是一个虚的字符,它代表一个位置,你也可以直观地认为“定位字符”所代表的是某个字符与字符间的那个微小间隙。
^  表示其后的字符必须位于字符串的开始处
$  表示其前面的字符必须位于字符串的结束处
/b  匹配一个单词的边界
/B  匹配一个非单词的边界
另外,还包括:/A  前面的字符必须位于字符串的开始处,/z  前面的字符必须位于字符串的结束处,/Z  前面的字符必须位于字符串的结束处,或者位于换行符前
下面提供一些简单的示例:

 1 string i = "Live for nothing,die for something";
 2 Regex r1 = new Regex("^Live for nothing,die for something$");
 3 //r1.IsMatch(i) true
 4 Regex r2 = new Regex("^Live for nothing,die for some$");
 5 //r2.IsMatch(i) false
 6 Regex r3 = new Regex("^Live for nothing,die for some");
 7 //r3.IsMatch(i) true
 8
 9 string i = @"Live for nothing,
10 die for something";//多行
11 Regex r1 = new Regex("^Live for nothing,die for something$");
12 Console.WriteLine("r1 match count:" + r1.Matches(i).Count);//0
13 Regex r2 = new Regex("^Live for nothing,die for something$", RegexOptions.Multiline);
14 Console.WriteLine("r2 match count:" + r2.Matches(i).Count);//0
15 Regex r3 = new Regex("^Live for nothing,/r/ndie for something$");
16 Console.WriteLine("r3 match count:" + r3.Matches(i).Count);//1
17 Regex r4 = new Regex("^Live for nothing,$");
18 Console.WriteLine("r4 match count:" + r4.Matches(i).Count);//0
19 Regex r5 = new Regex("^Live for nothing,$", RegexOptions.Multiline);
20 Console.WriteLine("r5 match count:" + r5.Matches(i).Count);//0
21 Regex r6 = new Regex("^Live for nothing,/r/n$");
22 Console.WriteLine("r6 match count:" + r6.Matches(i).Count);//0
23 Regex r7 = new Regex("^Live for nothing,/r/n$", RegexOptions.Multiline);
24 Console.WriteLine("r7 match count:" + r7.Matches(i).Count);//0
25 Regex r8 = new Regex("^Live for nothing,/r$");
26 Console.WriteLine("r8 match count:" + r8.Matches(i).Count);//0
27 Regex r9 = new Regex("^Live for nothing,/r$", RegexOptions.Multiline);
28 Console.WriteLine("r9 match count:" + r9.Matches(i).Count);//1
29 Regex r10 = new Regex("^die for something$");
30 Console.WriteLine("r10 match count:" + r10.Matches(i).Count);//0
31 Regex r11 = new Regex("^die for something$", RegexOptions.Multiline);
32 Console.WriteLine("r11 match count:" + r11.Matches(i).Count);//1
33 Regex r12 = new Regex("^");
34 Console.WriteLine("r12 match count:" + r12.Matches(i).Count);//1
35 Regex r13 = new Regex("$");
36 Console.WriteLine("r13 match count:" + r13.Matches(i).Count);//1
37 Regex r14 = new Regex("^", RegexOptions.Multiline);
38 Console.WriteLine("r14 match count:" + r14.Matches(i).Count);//2
39 Regex r15 = new Regex("$", RegexOptions.Multiline);
40 Console.WriteLine("r15 match count:" + r15.Matches(i).Count);//2
41 Regex r16 = new Regex("^Live for nothing,/r$/n^die for something$", RegexOptions.Multiline);
42 Console.WriteLine("r16 match count:" + r16.Matches(i).Count);//1
43 //对于一个多行字符串,在设置了Multiline选项之后,^和$将出现多次匹配。
44
45 string i = "Live for nothing,die for something";
46 string m = "Live for nothing,die for some thing";
47 Regex r1 = new Regex(@"/bthing/b");
48 Console.WriteLine("r1 match count:" + r1.Matches(i).Count);//0
49 Regex r2 = new Regex(@"thing/b");
50 Console.WriteLine("r2 match count:" + r2.Matches(i).Count);//2
51 Regex r3 = new Regex(@"/bthing/b");
52 Console.WriteLine("r3 match count:" + r3.Matches(m).Count);//1
53 Regex r4 = new Regex(@"/bfor something/b");
54 Console.WriteLine("r4 match count:" + r4.Matches(i).Count);//1
55 ///b通常用于约束一个完整的单词

(4)重复描述字符
“重复描述字符”是体现C#正则表达式“很好很强大”的地方之一:
{n}  匹配前面的字符n次
{n,}  匹配前面的字符n次或多于n次
{n,m}  匹配前面的字符n到m次
?  匹配前面的字符0或1次
+  匹配前面的字符1次或多于1次
*  匹配前面的字符0次或多于0次
以下提供一些简单的示例:

 1 string x = "1024";
 2 string y = "+1024";
 3 string z = "1,024";
 4 string a = "1";
 5 string b="-1024";
 6 string c = "10000";
 7 Regex r = new Regex(@"^\+?[1-9],?\d{3}$");
 8 Console.WriteLine("x match count:" + r.Matches(x).Count);//1
 9 Console.WriteLine("y match count:" + r.Matches(y).Count);//1
10 Console.WriteLine("z match count:" + r.Matches(z).Count);//1
11 Console.WriteLine("a match count:" + r.Matches(a).Count);//0
12 Console.WriteLine("b match count:" + r.Matches(b).Count);//0
13 Console.WriteLine("c match count:" + r.Matches(c).Count);//0
14 //匹配1000到9999的整数。
15 //http://www.cnblogs.com/sosoft/

(5)择一匹配
C#正则表达式中的 (|) 符号似乎没有一个专门的称谓,姑且称之为“择一匹配”吧。事实上,像[a-z]也是一种择一匹配,只不过它只能匹配单个字符,而(|)则提供了更大的范围,(ab|xy)表示匹配ab或匹配xy。注意“|”与“()”在此是一个整体。下面提供一些简单的示例:

 1 string x = "0";
 2 string y = "0.23";
 3 string z = "100";
 4 string a = "100.01";
 5 string b = "9.9";
 6 string c = "99.9";
 7 string d = "99.";
 8 string e = "00.1";
 9 Regex r = new Regex(@"^\+?((100(.0*)?)|([1-9]?[0-9])(\.\d+)?)$");
10 Console.WriteLine("x match count:" + r.Matches(x).Count);//1
11 Console.WriteLine("y match count:" + r.Matches(y).Count);//1
12 Console.WriteLine("z match count:" + r.Matches(z).Count);//1
13 Console.WriteLine("a match count:" + r.Matches(a).Count);//0
14 Console.WriteLine("b match count:" + r.Matches(b).Count);//1
15 Console.WriteLine("c match count:" + r.Matches(c).Count);//1
16 Console.WriteLine("d match count:" + r.Matches(d).Count);//0
17 Console.WriteLine("e match count:" + r.Matches(e).Count);//0
18 //匹配0到100的数。最外层的括号内包含两部分“(100(.0+)*)”,“([1-9]?[0-9])(/./d+)*”,这两部分是“OR”的关系,即正则表达式引擎会先尝试匹配100,如果失败,则尝试匹配后一个表达式(表示[0,100)范围中的数字)。

(6)特殊字符的匹配
下面提供一些简单的示例:

(7)组与非捕获组
以下提供一些简单的示例:

string x = "Live for nothing,die for something";string y = "Live for nothing,die for somebody";Regex r = new Regex(@"^Live ([a-z]{3}) no([a-z]{5}),die \1 some\2$");Console.WriteLine("x match count:" + r.Matches(x).Count);//1Console.WriteLine("y match count:" + r.Matches(y).Count);//0//正则表达式引擎会记忆“()”中匹配到的内容,作为一个“组”,并且可以通过索引的方式进行引用。表达式中的“/1”,用于反向引用表达式中出现的第一个组,即粗体标识的第一个括号内容,“/2”则依此类推。string x1 = "Live for nothing,die for something";Regex r1 = new Regex(@"^Live for no([a-z]{5}),die for some\1$");if (r1.IsMatch(x1)){Console.WriteLine("group1 value:" + r1.Match(x1).Groups[1].Value);//输出:thing
            }//获取组中的内容。注意,此处是Groups[1],因为Groups[0]是整个匹配的字符串,即整个变量x的内容。string x2 = "Live for nothing,die for something";Regex r2 = new Regex(@"^Live for no(?<g1>[a-z]{5}),die for some\1$");if (r2.IsMatch(x2)){Console.WriteLine("group1 value:" + r2.Match(x2).Groups["g1"].Value);//输出:thing
            }//可根据组名进行索引。使用以下格式为标识一个组的名称(?<groupname>…)。string x3 = "Live for nothing nothing";Regex r3 = new Regex(@"([a-z]+) \1");if (r3.IsMatch(x3)){x3 = r3.Replace(x3, "$1");Console.WriteLine("var x:" + x3);//输出:Live for nothing
            }//删除原字符串中重复出现的“nothing”。在表达式之外,使用“$1”来引用第一个组,下面则是通过组名来引用:string x4 = "Live for nothing nothing";Regex r4 = new Regex(@"(?<g1>[a-z]+) \1");if (r4.IsMatch(x4)){x4 = r4.Replace(x4, "${g1}");Console.WriteLine("var x:" + x4);//输出:Live for nothing
            }string x5 = "Live for nothing";Regex r5 = new Regex(@"^Live for no(?:[a-z]{5})$");if (r5.IsMatch(x5)){Console.WriteLine("group1 value:" + r.Match(x5).Groups[1].Value);//输出:(空)
            }//在组前加上“?:”表示这是个“非捕获组”,即引擎将不保存该组的内容。Console.Read();

(8)贪婪与非贪婪
正则表达式的引擎是贪婪,只要模式允许,它将匹配尽可能多的字符。通过在“重复描述字符”(*,+)后面添加“?”,可以将匹配模式改成非贪婪。请看以下示例:

 1 string x = "Live for nothing,die for something";
 2 Regex r1 = new Regex(@".*thing");
 3 if (r1.IsMatch(x))
 4 {
 5     Console.WriteLine("match:" + r1.Match(x).Value);//输出:Live for nothing,die for something
 6 }
 7 Regex r2 = new Regex(@".*?thing");
 8 if (r2.IsMatch(x))
 9 {
10     Console.WriteLine("match:" + r2.Match(x).Value);//输出:Live for nothing
11 }

(9)回溯与非回溯
使用“(?>…)”方式进行非回溯声明。由于正则表达式引擎的贪婪特性,导致它在某些情况下,将进行回溯以获得匹配,请看下面的示例:

 1 string x = "Live for nothing,die for something";
 2 Regex r1 = new Regex(@".*thing,");
 3 if (r1.IsMatch(x))
 4 {
 5     Console.WriteLine("match:" + r1.Match(x).Value);//输出:Live for nothing,
 6 }
 7 Regex r2 = new Regex(@"(?>.*)thing,");
 8 if (r2.IsMatch(x))//不匹配
 9 {
10     Console.WriteLine("match:" + r2.Match(x).Value);
11 }
12 //在r1中,“.*”由于其贪婪特性,将一直匹配到字符串的最后,随后匹配“thing”,但在匹配“,”时失败,此时引擎将回溯,并在“thing,”处匹配成功。
13 //在r2中,由于强制非回溯,所以整个表达式匹配失败。

(10)正向预搜索、反向预搜索
正向预搜索声明格式:正声明 “(?=…)”,负声明 “(?!...)” ,声明本身不作为最终匹配结果的一部分,请看下面的示例:

 1 string x = "1024 used 2048 free";
 2 Regex r1 = new Regex(@"/d{4}(?= used)");
 3 if (r1.Matches(x).Count==1)
 4 {
 5     Console.WriteLine("r1 match:" + r1.Match(x).Value);//输出:1024
 6 }
 7 Regex r2 = new Regex(@"/d{4}(?! used)");
 8 if (r2.Matches(x).Count==1)
 9 {
10     Console.WriteLine("r2 match:" + r2.Match(x).Value); //输出:2048
11 }
12 //r1中的正声明表示必须保证在四位数字的后面必须紧跟着“ used”,r2中的负声明表示四位数字之后不能跟有“ used”。

反向预搜索声明格式:正声明“(?<=)”,负声明“(?<!)”,声明本身不作为最终匹配结果的一部分,请看下面的示例:

 1 string x = "used:1024 free:2048";
 2 Regex r1 = new Regex(@"(?<=used:)/d{4}");
 3 if (r1.Matches(x).Count==1)
 4 {
 5     Console.WriteLine("r1 match:" + r1.Match(x).Value);//输出:1024
 6 }
 7 Regex r2 = new Regex(@"(?<!used:)/d{4}");
 8 if (r2.Matches(x).Count==1)
 9 {
10     Console.WriteLine("r2 match:" + r2.Match(x).Value);//输出:2048
11 }
12 //r1中的反向正声明表示在4位数字之前必须紧跟着“used:”,r2中的反向负声明表示在4位数字之前必须紧跟着除“used:”之外的字符串。

(11)十六进制字符范围
正则表达式中,可以使用 "/xXX" 和 "/uXXXX" 表示一个字符("X" 表示一个十六进制数)形式字符范围:
/xXX       编号在 0到255 范围的字符,比如:空格可以使用 "/x20" 表示。
/uXXXX   任何字符可以使用 "/u" 再加上其编号的4位十六进制数表示,比如:汉字可以使用“[/u4e00-/u9fa5]”表示。

(12)对[0,100]的比较完备的匹配
下面是一个比较综合的示例,对于匹配[0,100],需要特殊考虑的地方包括
*00合法,00.合法,00.00合法,001.100合法
*空字符串不合法,仅小数点不合法,大于100不合法
*数值是可带后缀的,如“1.07f”表示该值为一个float类型(未考虑)

 1 Regex r = new Regex(@"^/+?0*(?:100(/.0*)?|(/d{0,2}(?=/./d)|/d{1,2}(?=($|/.$)))(/./d*)?)$");
 2 string x = "";
 3 while (true)
 4 {
 5     x = Console.ReadLine();
 6     if (x != "exit")
 7     {
 8         if (r.IsMatch(x))
 9         {
10             Console.WriteLine(x + " succeed!");
11         }
12         else
13         {
14             Console.WriteLine(x + " failed!");
15         }
16     }
17     else
18     {
19         break;
20     }
21 }

(13)精确匹配有时候是困难的
有些需求要做到精确匹配比较困难,例如:日期、Url、Email地址等,其中一些你甚至需要研究一些专门的文档写出精确完备的表达式,对于这种情况,只能退而求其次,保证比较精确的匹配。例如对于日期,可以基于应用系统的实际情况考虑一段较短的时间,或者对于像Email的匹配,可以只考虑最常见的形式。

转载于:https://www.cnblogs.com/coky/p/6761049.html

【转】C#正则表达式教程和示例相关推荐

  1. java正则表达式用法示例_Java正则表达式教程及示例

    java正则表达式用法示例 当我开始使用Java时,正则表达式对我来说是一场噩梦. 本教程旨在帮助您掌握Java正则表达式,并让我定期返回以刷新我的正则表达式学习. 什么是正则表达式? 正则表达式定义 ...

  2. java正则表达式教程_Java正则表达式教程及示例

    [感谢 @CuGBabyBeaR 的热心翻译.如果其他朋友也有不错的原创或译文,可以尝试投递到 ImportNew.] 当我开始我的Java职业生涯的时候,对于我来说正则表达式简直是个是梦魇.本教程旨 ...

  3. c++正则表达式_Python正则表达式教程-常用文本处理技巧

    介绍: 正则表达式用于识别模式(pattern)是否存在于给定的字符(字符串)序列中.它们有助于处理文本数据,这通常是涉及文本挖掘的数据科学项目的先决条件.您一定遇到过一些正则表达式的应用程序:它们在 ...

  4. Java中的正则表达式 - Java Regex示例

    Java中的正则表达式 - Java Regex示例 欢迎使用Java中的正则表达式.它在Java中也称为Regex.当我开始编程时,java正则表达式对我来说是一场噩梦.本教程旨在帮助您掌握Java ...

  5. 正则表达式教程之模式修正符

    之前我们给大家介绍了正则表达式中的定界符.原子和元字符,那么我们关于正则表达式教程的基本语法就剩下了正则表达式中的模式修正符.本节会向大家介绍模式修正符的概念.模式修正符的构成,以及结合实例的模式修正 ...

  6. 正则表达式--教程一 简介(共三篇)

    正则表达式--教程二(语法):https://blog.csdn.net/alzzw/article/details/99470144 正则表达式--教程三(匹配规则及示例):https://blog ...

  7. 正则表达式--教程二(语法)

    正则表达式--教程一 简介(共三篇):https://blog.csdn.net/alzzw/article/details/99463959 正则表达式--教程三(匹配规则及示例):https:// ...

  8. 很好的正则表达式教程

    版本:v2.21 (2007-8-3) 作者:deerchao 来源:unibetter大学生社区 转载请注明来源 本文目标 如何使用本教程 正则表达式到底是什么? 入门 测试正则表达式 元字符 字符 ...

  9. 正则表达式教程: 开始

    原文:Regular Expressions Tutorial: Getting Started 作者:Tom Elliott 译者:kmyhy 在这篇教程中,你将学习如何在 iOS app 中使用 ...

  10. Awk打印教程及示例

    Awk is a stream type programming language. Awk can edit given text ant provided new text according t ...

最新文章

  1. 内存管理-定时器循环、内存布局、tagged pointer、weak指针、copy、自动释放池
  2. 我是清华新任教授张亚勤,现在只想做成这一件事
  3. Flume监听文件夹中的文件变化,并把文件下沉到hdfs
  4. 如何把HTML转换成动图,html5实现图片转圈的动画效果——让页面动起来
  5. ui自动化测试测试报告_您需要了解的有关UI测试的所有信息
  6. spark学习-34-Spark的BroadcastManager广播管理器
  7. 移动互联网时代,学iOS开发好吗
  8. matlab 逻辑斯蒂回归,梯度下降法解逻辑斯蒂回归
  9. 微信小程序之保存图片到手机相册
  10. 论文翻译 | R-CNN论文:《Rich feature hierarchies for accurate object detection and semantic segmentation》
  11. 正版cs跳跃服务器,反恐精英 玩CS1.6跳跃服务器
  12. php blowfish 解密,php blowfish加密解密算法
  13. webpack抽离 公共代码
  14. 拓展名为html包括,在Windows中,帮助文件的扩展名为()。选项: a、“.html” b、“.sys” c、“.h...
  15. 过期域名查询php程序,一个域名查询的程序
  16. 2021互联网大厂端午礼盒大盘点~
  17. ViewModel是如何在配置更改后继续留存数据的
  18. Android studio使用.9图片报错
  19. 案例爬取(其一):url获取
  20. Android OpenGLES2.0(一)——了解OpenGLES2.0

热门文章

  1. Spring Boot系列(一)——初识Spring Boot
  2. 64位Windows7环境下,Eclipse集成svn后出现Failed to load JavaHL Library的解决办法
  3. 单元素的枚举类型已经成为实现Singleton的最佳方法
  4. mysql数据库增删改操作不自动提交事务
  5. 详解JavaScript的闭包
  6. 解决LINQ to Entities does not recognize the method 'System.String Encrypt(System.String)' method, and
  7. C++11 thread_local
  8. 斐波那契查找算法中为什么需要把数组长度扩充到f[k]-1而不是f[k]或者f[k+1]
  9. 微服务学习之OpenFeign【Hoxton.SR1版】
  10. ahb总线协议主机_AMBA总线协议之一文看懂AMBA2 AHB2与AMBA3 AHBLite总线协议的区别