今日随笔,继续写一点关于正则表达式的 知识。前两天介绍了正则表达式验证匹配,提取等一些基本的知识,今天继续分享下它的另一个强大的应用:替换(replace)。

开始之前,还是要补一下昨天的内容。

在我们昨天的内容里,有一个提取组的概念,在上一节中,我么只用了数值索引来获取某组的value。我们还可以给某个组取一个别名,然后通过别名来找到相应的组的value。

我们还拿昨天的name和age那个例子说明:

 1  //----------------------------------通过数值索引-------------------
 2             string regex = @"name=(\w+)age=(\d{0,2})";
 3             string str = "name=小强age=23";
 4             Match match = Regex.Match(str, regex);
 5 
 6             Console.WriteLine("name:{0},age:{1}", match.Groups[1].Value, match.Groups[2].Value);
 7 
 8             //输出结果 name:小强,age:23
 9             //----------------------------------end-------------------
10 


11 //-------------------------------------通过别名------------------------------ 12 string regex = @"name=(?<name>\w+)age=(?'age'\d{0,2})"; 13 string str = "name=小强age=23"; 14 Match match = Regex.Match(str, regex); 15 16 Console.WriteLine("name:{0},age:{1}", match.Groups["name"].Value, match.Groups["age"].Value); 17 Console.WriteLine("COUNT:" + match.Groups.Count); 18 for (int i = 0; i < match.Groups.Count; i++) 19 { 20 Console.WriteLine("{0}--------->{1}", i, match.Groups[i].Value); 21 } 22 23 //输出结果 name:小强,age:23 24 //COUNT:3 25 //0---------->name=小强age=23 26 //1---------->小强 27 //2---------->23

首先,要先说一下这是微软支持组别名的语法,在PHP,Python中,可以用(?P﹤name﹥group)来对组进行命名。词法?P﹤name﹥就是对组(group)进行了命名。其中name是你对组的起的名字。你可以用(?P=name)进行引用(一会会介绍引用这个东东)。

NET framework也支持命名组。不幸的是,微软的程序员们决定发明他们自己的语法,而不是沿用Perl、Python的规则。

(?﹤name﹥小强)(?’age’ 23),

如你所看到的,.NET提供两种词法来创建命名组:一是用尖括号“?﹤﹥”,或者用单引号“?'' ”。尖括号在字符串中使用更方便,单引号在ASP代码中更有用,因为ASP代码中“﹤﹥”被用作HTML标签。

恩。。。,今天还要补一组别名的另一个应用:“正则表达式组之重复操作与后向引用

  当用“()”定义了一个正则表达式组后,正则引擎则会把被匹配的组按照顺序编号,存入缓存。当对被匹配的组进行向后引用的时候,可以用“\数字”的方式进行引用。“\1”引用第一个匹配的后向引用组,“\2"引用第二个组,以此类推,"\n"引用第n个组。而"\0"则引用整个被匹配的正则表达式本身。我们看一个例子。

假设你想匹配一个HTML标签的开始标签和结束标签,以及标签中间的文本。比如﹤B﹥This is a test﹤/B﹥,我们要匹配﹤B﹥和﹤/B﹥以及中间的文字。我们可以用如下正则表达式:“﹤([A-Z][A-Z0-9]*)[^﹥]*﹥.*?﹤/\1﹥”

首先,“﹤”将会匹配“﹤B﹥”的第一个字符“﹤”。然后[A-Z]匹配B,[A-Z0-9]*将会匹配0到多次字母数字,后面紧接着0到多个非“﹥”的字符。最后正则表达式的“﹥”将会匹配“﹤B﹥”的“﹥”。接下来正则引擎将对结束标签之前的字符进行惰性匹配,直到遇到一个“﹤/”符号。然后正则表达式中的“\1”表示对前面匹配的组“([A-Z][A-Z0-9]*)”进行引用,在本例中,被引用的是标签名“B”。所以需要被匹配的结尾标签为“﹤/B﹥”

  

你可以对相同的后向引用组进行多次引用,([a-c])x\1x\1将匹配“axaxa”、“bxbxb”以及“cxcxc”。如果用数字形式引用的组没有有效的匹配,则引用到的内容简单的为空。

一个后向引用不能用于它自身。([abc]\1)是错误的。因此你不能将﹤﹤\0﹥﹥用于一个正则表达式匹配本身,它只能用于替换操作中。

代码如下:

            string regex = @"name=(\w+),waihao=\1";
            //string regex = @"([a-c])x\1x\1";
            while (true)
            {
                string str = Console.ReadLine();
                Console.WriteLine(Regex.IsMatch(str, regex));
            }

//输入:name=小强,waihao=小强
//输出的是True

好啦,昨天的内容,就补到这,现在让我们看看正则表达式中替换的用法。

 

啥也不说,还是先上例子

            #region 正则表达式字符串替换,将连续的a都替换成a

            ////1.你aaa好aa哈哈a你

            //string msg = "你aaa好aa哈aaaaa哈a你";
            //msg = Regex.Replace(msg, "a+", "a");
            //Console.WriteLine(msg);
            //Console.ReadKey();
            #endregion

            #region 练习2:将连续的-都替换成一个-

            //string msg = "234-----234--------------34------55";
            //msg = Regex.Replace(msg, @"\-+", "-");
            ////Regex.Split();
            //Console.WriteLine(msg);
            //Console.ReadKey();

            #endregion

            #region 替换案例:将hello 'welcome' to 'China'   替换成 hello 【welcome】 to 【China】
            ////hello 【welcome】 to 【China】
            ////'slslls'   【slslls】
            //string msg = "hello 'welcome' to 'China'";
            ////msg.Replace("'","】"
            //正则表达式的替换中也可以使用提取组,使用()来分组,使用$n,来引用提取组。
            //msg = Regex.Replace(msg, "'(.+?)'", "【$1】");
            //Console.WriteLine(msg);
            //Console.ReadKey();

            #endregion

替换:顾名思义就是把一个字符串中,与正则表达式模式匹配的地方,给替换成我们想要的部分。用的是Regex的Replace方法。。。

Replace: 在指定的输入字符串内,使用指定的替换字符串替换与指定正则表达式匹配的所有字符串。返回结果:一个与输入字符串基本相同的新字符串,唯一的差别在于,其中的每个匹配字符串已被替换字符串代替。

在上面的三个例子中,前两个很简单了,我就不说了,有一点要注意的是”-“是元字符,所以要转义一下。

第三个例子我要说一下,这里要注意两点,一点事提取组的用法:例子中要把说有用引号包起来的地方都替换成 用【】包起来,那么我们先定义一个正则表达式模式regex='(.+?)',这里我们把引号之间的内容括了起来作为一个提取住,然后在replac方法的第三个参数中,我们可以用$1代替刚才那个提取组的内容(因为引号之间的内容是第一组,所以这里用的是$1)。同时,还要注意一点的就是在”.+“的后面加了一个问号,这就是我们前面所说的终止贪婪模式,如果不加得话,以为welcome' to 'China 都属于"."这个元字符的匹配的范围内,所以最终匹配的结果将会是hello 【welcome' to 'China】。

Repalce方法有一个重载,第三个参数是穿进去一个委托实例(方法),在这个方法中,你可以自己定义具体要怎么替换或者是做相应的操作,然后将string结果返回。这个就先不举例子了,在今后我会专门写一个委托的系列和大家分享。

好啦,再给大家上几个例子,正则表达式就告于段落了,这三篇文章知识讲了一些正则表达式的基本用法,和一些应用的列子(在这些应用中,有的正则表达式模式定义的不是很精确,比如上一节中匹配email,上上节中的匹配身份证等等,在这里主要的目的是举例子介绍正则表达式,而没有去写较精确的匹配模式),它还有更多的应用和用法,大家在工作中继续探讨和学习吧。

 

#region 手机号码隐去中间四位
            //string msg = "我叫杨中科:13488888888我是苏坤18999141365。蒋坤:13111111111。";
            //msg = Regex.Replace(msg, @"(\d{3})\d{4}(\d{4})", "$1****$2");
            //Console.WriteLine(msg);
            //Console.ReadKey();
            #endregion

            #region 练习1:将一段文本中的MM/DD/YYYY格式的日期转换为YYYY-MM-DD格式 ,比如“我的生日是05/21/2010耶”转换为“我的生日是2010-05-21耶”。

            //string msg = "我的生日是05/21/2010耶,TA的生日是:06/09/2000,哦耶耶";

            //msg = Regex.Replace(msg, @"(\d{2})/(\d{2})/(\d{4})", "$3-$1-$2");
            //Console.WriteLine(msg);
            //Console.ReadKey();

            #endregion

            //a+?
            //xaaaaaaaab

            #region 练习2:给一段文本中匹配到的url添加超链接,比如把http://www.test.com替换为<a href="http://www.test.com"> http://www.test.com</a>。

            //string msg = "比如把http://www.test.com,新浪http://www.sina.com百度http://www.baidu.com网易:http://www.163.com。传智播客http://net.itcast.cn。";

            //msg = Regex.Replace(msg, @"(http://[a-zA-Z0-9_\-\.&\?]+)", "<a href=\"$1\">$1</a>");
            //Console.WriteLine(msg);
            //Console.ReadKey();
            #endregion

 

恩。。给自己的博客做个广告吧,这段时间正在写一个关于asp.net运行机制的系列,希望更多的小伙伴们可以去给 出指点。

 

【原创】前言  

【原创】asp.net内部原理(一) 第一个版本  

【原创】asp.net内部原理(二) 第二个版本  

 

好啦,亲爱的小伙伴们,我们一起加油吧,坚信我的老师跟我说的一句话,写程序也是一种艺术,程序员是一名艺术家,而不是苦逼。 ^_^  Come On~~ GO!GO!.

posted on 2013-09-05 07:25  Flx  阅读(1621)  评论(2编辑  收藏  举报