`

正则表达式解惑

阅读更多

使用正则表达式(组的概念/拆分字符串)

正则表达式(Regular expressions)是一套语法匹配规则,各种语言,如Perl .NetJava都有其对应的共享的正则表达式类库。在.Net中,这个类库叫做Regex

简单的说,Regex是从字符窗中查找匹配字符串的应用类。通过Regex,编程人员能够非常方便的从一段数据中提取自己所需要的数据信息。举一个简单的例子,让大家对Regex有个大概的了解:

 

结果很明显,regex为我们找到了字符串”fox 9212gold”中的数字字符串,输出结果为”9212” .

       Regex有了一个基本的概念之后,我需要告诉你一个非常好的消息,那就是Regex可以为我们做的远不止这么一点点,他是一套功能非常强大语法匹配规则。当然,这里还有一个坏消息等着我们,那就是强大功能的语法规则自然需要大量纷繁复杂的keyword支持,这也为Regex的学习带来了极大的难度。想要真正掌握正则表达式,可不是几个sample能够全部揭示与说明的。

 

创建一个Regex对象

       Regex的构造函数有三种,在这里就不讨论默认构造函数了。另外两个构造函数中,一个构造函数接收正则表达式字符串作为入参,另一个以正则表达式字符串和RegexOptions作为入参。如:

Regex regex = new Regex("\w+$");

Regex regex = new Regex("\s+", RegexOptions.IgnoreCase | RegexOptions.Multiline);

RegexOptions可以为我们提供一些特殊的帮助,比如IgnoreCase能够在匹配是忽略大小写,Multiline能够调整^$的意义,改为匹配一行的开头和结尾。

上面我们构造了一个正则表达式,只不过我们还没有用它来做任何事情,马上我们就可以通过使用下面的几个方法,实现对字符串对象的操作了。

匹配字符串

       Regex有两个获取匹配的方法Match()Matches(),分别代表匹配一个,匹配多个结果。这里就用Matches来展示一下怎么使用Regex获取匹配字符串,并将其显示出来。

         public static void showMatches(string expression, RegexOptions option, string ms)                 

         {                                                                                                    

                   Regex regex = new Regex(expression, option);                                             

                   MatchCollection matches = regex.Matches(ms);                                           

                   //show matches                                                                                  

                   Console.WriteLine("////////////////----------------------------------////////////////");                     

                   Console.WriteLine(" string: \"{0}\"\r\n expression: \"{1}\"\r\n match result is:",             

                  ms, expression);                                                                                

                   foreach(Match m in matches)                                                          

                   {                                                                                                                        Console.WriteLine("match string is: \"{0}\", length: {1}",                       

                           m.Value.ToString(), m.Value.Length);                                            

                   }                                                                                           

                   Console.WriteLine("matched count: {0}", matches.Count);                                   

         }                                                                                                    

 

方法Matched通过比较入参字符串和正则表达式,找到所有符合的结果,并将结果作为MatchCollection传出来。这样,只要简单的遍历这个collection,就可以很快的获得所有的结果。

 

组的概念

 

       当你获得这样的一个字符串最后比分是:19/24”,你肯定希望有一个正则表达式,他不单能够找到形如 data1/data2的字符串,还应该能够直接把data1,data2作为单独的结果传送出来。否则你需要再对形如”19/24”的字符串进行分析,才能够顺利得到双方的比分。显然,正则表达式不会忽略这个问题,所以他增加了组的概念。你可以把一次搜索的结果分别放入不同的组中,并通过组名或者组的所以分别取得这些组的结果。比如上例,我们就可以用@”(\d+)/(\d+)”作为表达式。来看看结果吧:

 

那么如何区分组呢?

用一对()括起来的正则就是一个组。

例如:reg = ([a-z])(\.)(\d) 这个正则表达式有三对短号,就有三个组:[a-z] .和\d 这三个数

str = "a.4g"

匹配的结果为 a.4

对应的组为:

$0=a.4

$1=a

$2=.

$3=d

如果reg = ([a-z])\.\d 这个正则只有一个括号,就只有一个组[a-z]

str="a.4g"匹配结果为a.4,对应的组为

$0=a.4

$1=a

 

                            Regex regex = new Regex(@"(\d+)/(\d+)");                                             

                            MatchCollection matches = regex.Matches(@"最后比分是:19/24");        

                            //show matches                                                                         

                            Console.WriteLine("////////////////----------------------------------////////////////");            

                            foreach(Match m in matches)                                                 

                            {                                                                                  

                                     //Console.WriteLine("match string is: \"{0}\", length: {1}",                                                 // m.Value.ToString(), m.Value.Length);                                 

                                     foreach(string name in regex.GetGroupNames())                      

                                     {                                                                        

                                               Console.WriteLine("\r capture group \"{0}\" value is:\"{1}\""        

                                              , name, m.Groups[name].Value);                                 

                                     }                                                                        

                            }                                                                                  

                            Console.WriteLine("matched count: {0}", matches.Count);                         

 

输出:

////////////////----------------------------------////////////////

 capture group "0" value is:"19/24"

 capture group "1" value is:"19"

 capture group "2" value is:"24"

matched count: 1

 

现在清楚了吧,Regex对象把匹配的结果放入组0中。同时,匹配的组信息也放入了对应的组中。组的名称在默认的情况下,是从1开始依次增加的整数。0作为保留名称,专门用于指示匹配的整个字符串。既然有默认情况这样的概念,自然也就意味着用户可以自定义组的名称。方法很简单,在组的前面加上:?<name>就可以了。好了,现在把前面的正则表达式修改一下,换成@”(?<score1>\d+)/(?<score1>\d+)”,现在再看看结果:

////////////////----------------------------------////////////////

 capture group "0" value is:"19/24"

 capture group "score1" value is:"19"

 capture group "score2" value is:"24"

matched count: 1

 

换成自己定义的名字了吧,哈哈!为了在今后的测试中,能够更加方便的看到所有结果,我们对前面介绍过的showMatches()做一点小小的调整。这样,如果在表达式中包含了组的定义,我们也可以在不需要修改任何代码的情况下,直接看到所有的组信息了,调整后的方法showMatchesPro()如下:

         public static void showMatchesPro(string expression, RegexOptions option, string ms)          

         {                                                                                                    

                   Regex regex = new Regex(expression, option);                                             

                   MatchCollection matches = regex.Matches(ms);                                           

                   //show matches                                                                                  

                   Console.WriteLine("////////////////----------------------------------////////////////");                     

                   Console.WriteLine(" string: \"{0}\"\r\n expression: \"{1}\"\r\n match result is:",             

                  ms, expression);                                                                                

                   foreach(Match m in matches)                                                          

                   {                                                                                                                       foreach(string name in regex.GetGroupNames())                                

                            {                                                                                  

                                     Console.WriteLine("\r capture group \"{0}\" value is:\"{1}\"",                

                                     name, m.Groups[name].Value);                                            

                            }                                                                                  

                   }                                                                                           

                   Console.WriteLine("matched count: {0}", matches.Count);                                   

                   // show group name                                                                 

                  Console.WriteLine("group name count {0}", regex.GetGroupNames().Length);                 

                   foreach(string name in regex.GetGroupNames())                                         

                   {                                                                                           

                            Console.WriteLine("group name :\"{0}\"", name);                                 

                   }                                                                                           

         }                                                                                                    

 

替换字符串

Regex也提供了方便的匹配结果替换的功能。为了方便测试,我们也把他写成方法,代码如下:

        public static string replaceMatch(string expression, RegexOptions option, string ms, string rep)     

         {                                                                                                    

                   Regex regex = new Regex(expression, option);                                             

                   string result = regex.Replace(ms, rep);                                                  

                   Console.WriteLine("////////////////----------------------------------////////////////");                     

                   Console.WriteLine("string: \"{0}\", expression:\"{1}\", replace by : \"{2}\"",                    

                  ms, expression, rep);                                                                        

                   Console.WriteLine("replace result string is: \"{0}\", length: {1}",                                    

                                    result.ToString(), result.Length);                                            

                            return result;                                                                     

          }                                                                                                                                                                                                                

 

Regex.Replace通常接受两个string作为入参,第一个string为输入字符串。第二个字符串用来替代匹配字符串,它可以包含一些特殊字符串,用来代表特别转换。

 

特殊字符串                      替换结果

$&               匹配的字符串,也可以用$0

$1, $2, . . .    匹配字符串中的对应组,用索引标示

${name}      匹配字符串中的对应组,用名称标示

$‘              匹配位置之前的字符串

$’              匹配位置之后的字符串

$$         一个$字符

$_          输入字符串

$+         匹配字符串的所有组中,最后一个组中的数据

 

是不是看了这么多怪型怪状的特殊字符串,有点头晕了?嗯,那就弄两个sample来看看结果吧!

Sample1:

replaceMatch(@"\d+", RegexOptions.None, "fef 12/21 df 33/14   727/1", "<<$&>>");

输出,所有数字型的数据都被替换成了<<data>>

////////////////----------------------------------////////////////

string: "fef 12/21 df 33/14   727/1", expression:"\d+", replace by : "<<$&>>"

replace result string is: "fef <<12>>/<<21>> df <<33>>/<<14>>   <<727>>/<<1>>",

length: 50

 

Sample2:

replaceMatch(@"(\d+)/(\d+)", RegexOptions.None, "fef 12/21 df 33/14   727/1", "$+");

输出,所有data1/data2匹配的数据,都被替换成了data2

////////////////----------------------------------////////////////

string: "fef 12/21 df 33/14   727/1", expression:"(\d+)/(\d+)", replace by : "$+"

replace result string is: "fef 21 df 14   1", length: 16

 

怎么样,Regex的功能够丰富的吧!可是,也许你的需求不光这么简单,比如说,你要把”I have 200 dollars”中间的money加倍,怎么办?我晕倒,好像没有现成的东西可以用。没有关系,Regex还有更好的功能。它允许你自己定义转换公式。

using System.Text.RegularExpressions;                                                                  

class RegularExpressions                                                                                          

{                                                                                                              

   static string CapText(Match m)                                                                              

   {                                                                                                        

         // Get the matched string.                                                                           

         string x = m.ToString();                                                                               

         // double this value                                                                             

         string result = (int.Parse(x) * 2).ToString();                                                                

         return result;                                                                                        

   }                                                                                                            

   static void Main()                                                                                            

   {                                                                                                        

         string text = "i have 200 dollars";                                                                        

         string result = Regex.Replace(text, @"\d+",                                                              

         new MatchEvaluator(RegularExpressions.CapText));                                                     

         System.Console.WriteLine("result=[" + result + "]");                                                

   }                                                                                                        

}                                                                                                              

 

看看结果,太好了,我的钱真的变成了两倍!

但本文的目的是希望提供给大家一个方便好用的测试类,因此我们重载上面的repalceMatch方法,也允许自定义转换公式作为入参:

         public static string replaceMatch(string expression, RegexOptions option, string ms,               

                                    MatchEvaluator evaluator)                                                       

                   {                                                                                           

                            Regex regex = new Regex(expression, option);                                    

                            string result = regex.Replace(ms, evaluator);                                        

                            Console.WriteLine("////////////////----------------------------------////////////////");            

                            Console.WriteLine("string: \"{0}\", expression:\"{1}\", replace by a evaluator.", ms,    

                                                       expression);                                          

                            Console.WriteLine("replace result string is: \"{0}\", length: {1}", result.ToString(),     

                                                       result.Length);                                      

                            return result;                                                                     

                   }                                                                                           

 

拆分字符串

 

Regex还提供了从匹配位置将字符串拆分的方法Split。这个方法同样具有多个重载,不过这些都不是重点,大家可以自己看文档。我们继续完成我们用于测试的方法:

                   public static void splitMatch(string expression, RegexOptions option, string ms)              

                   {                                                                                           

                            Regex regex = new Regex(expression, option);                                    

                            string[] result = regex.Split(ms);                                                      

                            Console.WriteLine("////////////////----------------------------------////////////////");            

                            Console.WriteLine("string: \"{0}\", expression: \"{1}\", split result is:", ms,                  

                                               expression);                                                   

                            foreach(string m in result)                                                                

                            {                                                                                  

                                     Console.WriteLine("splited string is: \"{0}\", length: {1}",           

                                              m.ToString(), m.Length);                                       

                            }                                                                                  

                            Console.WriteLine("splited count: {0}", result.Length);                                 

                   }                                                                                           

代码简单,不多做解释。直接来一个smaple看看结果:

splitMatch(@"/",RegexOptions.None,  "2004/4/25");

输出:

////////////////----------------------------------////////////////

string: "2004/4/25", expression: "/", split result is:

splited string is: "2004", length: 4

splited string is: "4", length: 1

splited string is: "25", length: 2

splited count: 3

 

结果很明显,收工。

 

我的目的</s
分享到:
评论

相关推荐

    一些关于greta的东东

    3. **`匹配相对url - 答疑解惑 - 正则表达式论坛 正则表达式论坛正则表达式Regular Expressionregex - Powered by Discuz!.mht`**:这可能是一个论坛讨论,专注于使用正则表达式匹配相对URL。相对URL是相对于当前...

    爬取猫眼电影的排行榜前100名

    其次,正则表达式(Regular Expression)是一种强大的文本处理工具,用于匹配、查找、替换等操作。在这个项目中,我们利用正则表达式解析HTML页面,提取出电影的名称、评分、评价人数等关键信息。正则表达式的使用...

    Python学习资料学习课件python基础源码.zip

    058论一只爬虫的自我修养6:正则表达式2 059论一只爬虫的自我修养7:正则表达式3 060论一只爬虫的自我修养8:正则表达式4 061论一只爬虫的自我修养9:异常处理 062论一只爬虫的自我修养10:安装Scrapy 063论一只爬虫...

    python从入门到精通地址.txt

    060论一只爬虫的自我修养8:正则表达式4 P62. 061论一只爬虫的自我修养9:异常处理 P63. 062论一只爬虫的自我修养10:安装Scrapy P64. 063论一只爬虫的自我修养11:Scrapy框架之初窥门径 P65. 064GUI的终极选择...

    《语音与语言处理》第三版(草稿)-《Speech and Language Processing, 3rd edition draft》

    本书首先介绍了自然语言处理的基础知识,包括正则表达式、文本规范化、编辑距离等概念。正则表达式用于匹配文本中的模式,而文本规范化则是将文本转换成统一格式的过程,这在处理自然语言时尤为关键。编辑距离用于...

    Python爬虫高级开发工程师5期-视频教程网盘链接提取码下载.txt

    - **正则表达式**:深入理解正则表达式的语法,灵活应用于数据清洗与匹配任务中。 - **数据存储方案**:探索不同数据库(如MySQL、MongoDB)的特点,根据实际需求选择合适的数据存储方式。 #### 四、反爬虫策略应对...

    eloquentJS:Marijn Haverbeke的《 Eloquent JavaScript 3rd Edition》一书中的练习

    7. **正则表达式**:学习如何编写和使用正则表达式进行字符串的匹配和替换。 8. **DOM操作**:学习如何使用JavaScript操作HTML文档对象模型,包括元素的选择、添加、删除、属性修改等。 9. **异步编程**:回调函数...

    labuladong的算法小抄完整版.pdf

    - 提供了一些在线平台,用以练习和提高对Git、SQL以及正则表达式的应用能力。 ### 第一章:动态规划系列 #### 动态规划解题套路框架 - 动态规划题目的解题步骤和框架,为读者提供解题模板。 #### 动态规划设计 - ...

    java解惑很全的题目

    这部分可能包含有关字符编码、字符串操作、正则表达式等方面的问题。Java的`Character`类提供了许多处理单个字符的方法,`String`类则提供了丰富的字符串操作函数。 这些谜题覆盖了Java编程的多个方面,通过解答...

    2021最新java面试合集pdf.rar

    正则表达式.pdf 消息中间件面试专题及答案.pdf 深入浅出Redis.pdf 爱奇艺2021Java方向笔试题.docx 爱奇艺2021Java方向笔试题(第一场).docx 看透springMvc源代码分析与实践.pdf 网易2021招聘笔试- 系统开发研发...

    计算机答案 编译原理答案

    在学习《编译原理》时,学生需要掌握正则表达式、上下文无关文法、巴科斯范式(BNF)、LL和LR解析、逆波兰表示法、寄存器分配等核心概念。此外,了解编译器设计工具,如ANTLR、Flex和Bison,以及静态类型和动态类型...

    菲菲更名宝贝 菲菲更名宝贝

    ■ 高级文件名变更:包括正则表达式、Pascal脚本更名、文件名编辑器、汉字转拼音、文件名编码与解码、数字与汉字的转换、文件名编码格式转换、文件名内码转换、文件名加密解密等重磅功能 ■ 扩展名变更:包括智能...

    finndy-cloud-master.zip

    2. **规则配置**:用户可以通过设定规则来确定如何抓取特定网站的数据,这可能涉及到正则表达式、DOM解析等技术,以匹配和提取目标信息。 3. **数据处理**:采集到的数据往往需要清洗和预处理,比如去除HTML标签、...

    SpeedPHP开发手册

    - Router:SpeedPHP的路由系统支持正则表达式,可以灵活地定义路由规则,匹配不同URL请求到相应的控制器和方法。 - Loader:自动加载类库,遵循PSR-4规范,简化了类的引用和加载。 - Session和Cookie管理:提供...

    疯狂Python讲义第二章课后习题

    学习者需要掌握正则表达式(re模块)的基础知识,用于进行复杂文本处理。 11. **输入与输出**:了解如何读写文件,以及基本的文本和二进制文件操作。掌握print()函数和input()函数的使用。 12. **面向对象编程**:...

    python标准库

    字符串处理是NLP中的一个重要环节,string模块包含了对字符串操作的基础函数,而re模块提供了正则表达式的功能,能够对文本进行搜索、替换和解析等操作。在处理自然语言时,这些模块能够帮助程序员进行文本清洗、...

    Python语法:字符串操作.rar

    在进行文本处理时,正则表达式库`re`非常有用。它可以进行复杂的模式匹配和搜索替换,例如`import re; re.findall(r"\b[A-Z][a-z]+\b", "Hello, World!")`将返回所有首字母大写的单词列表。 在机器学习和人工智能...

    JS-Toy-Problems:从初学者到高级水平的玩具问题

    7. **正则表达式**:学习正则的基本语法和模式,用于数据验证和字符串操作。 8. **模块化**:了解CommonJS和ES6模块,如何通过import和export进行模块导入导出。 9. **DOM操作**:学习如何使用JavaScript操作DOM...

    LR模型的Python实现

    Sigmoid函数表达式为:f(x) = 1 / (1 + e^-x),其输出值介于0和1之间,非常适合表示概率。 二、Python实现LR模型的库 在Python中,我们可以使用Scikit-learn、statsmodels等库来实现LR模型。其中,Scikit-learn是...

Global site tag (gtag.js) - Google Analytics