• 正则表达式小记


    先来看下面一个例子,解析如下IP:

    192.160.1.234[port=8080,type=ftp]

    将上述表达式中的IP地址,端口号和端口类型提取出来。

    没有正则表达式之前,大家猛的一看,估计崩溃了。没办法,用string类的方法截取呗。于是,我们写下了如下代码:

    string str = "192.160.1.234[port=8080,type=ftp]";

                int indexIP = str.IndexOf("[");

                string ip = str.Substring(0, indexIP);

                //获取端口号

                int serverestart = str.IndexOf("=");

                int serverend=str.IndexOf(",");

                string server = str.Substring(serverestart+1,serverend-serverestart-1);

                //提取协议类型

                int typestart = str.LastIndexOf("=");

                int typeend = str.LastIndexOf("]");

                string type = str.Substring(typestart+1,typeend-typestart-1);

                string result = string.Format("IP是:{0},端口号是:{1},协议类型是:{2}",ip,server,type);

                MessageBox.Show(result);

    接下来,咱们来看下正则表达式能够做什么

    正则表达式能够做什么?

    正则表达式的用途十分广泛,使用正则表达可以验证用户输入的邮箱格式是否合法,可以获取网页上的邮箱,获取网页上的美图,网站上的职位信息等。

    什么是正则表达式?

    正则表达式就是一个字符串,正则表达式是用来匹配数据的,和语言无关,在js中也要用到。正则表达式类似于通配符,但又不仅仅是通配符。

    注意:不要想着一次性写出通用的正则表达式,够用就行,不行再改。

    下面,我们开始进入正题,来看下正则表达式中用于匹配的元字符

    元字符(匹配)

    01,      通用字符:点

    含义:除了换行之外的所有字符

    02,      选择字符:[]

    含义:一对中括号匹配一个字符

    03,      逻辑或:|

    含义:和C#中|含义一样

    04,      优先级与分组:()

    紧接着,我们来介绍下用于限定的元字符

    元字符(限定符):

    01,      任意个字符(包含0个):*

    02,      任意个字符(不含0个):+

    03,      是否有:?

    04,      N次重复:{n}

    05,      至少n次{n,}

    06,      N到m次{n,m}

    注意:限定符是仅限当前字符(就是前面一个)

    元字符(开始与结束):

    01,      开头与否定:^

    限定必须开头匹配

    在[]中使用表示不出现里面的字符

    02,      结束与编组:$

    限定必须结束匹配

    在分组后引用数据

    常用的元字符

    01,      数字与非数字

    数字:d

    非数字:D

    02,空字符与非空字符

              空字符:s

           非空字符;S

             可以匹配空格和换行

    03,文字与非文字

      文字(数字,字母和汉字,不包含标点符号):

       文字:w

      非文字:W

    注意点:

    字符串转义与c#转义相同

    d:digital

    s:space

    w:word

    哎!说了这么多,下面咱们通过一个例子来看下在.Net中如何使用正则表达式

    .Net中的正则表达式

     在.Net中我们使用Regex类来书写正则表达式

    Regex的常用方法:

    IsMatch():判断是否匹配

    Match():字符串提取

    Matches():循环提取

    Replace():Replace()

    下面来看一个字符串匹配的案例:

    案例:匹配正确的身份证号码(15或18位数字,18位数字后可能有X)

    分析:这里我们可以使用Regex的静态方法IsMatch来判断是否匹配,其中第一个参数为字符串,第二个参数为正则表达式

    bool flag=  Regex.IsMatch(txtphone.Text, @"^(d{3,4}-?d{7,8}|d{11}|d{5})$");

    接下来,咱们来看一个字符串提取的案例:

    案例:抓取某网站的所有邮箱。注意:这里是字符串提取,而不是匹配,所以^和$没有必要书写。

    分析:在解决这个问题之前,先给大家介绍一个类WebClient。该类的DownLoadString()方法能获取到指定网址的html代码

    。下面是实现代码:

              WebClient wc = new WebClient();

                wc.Encoding = Encoding.Default;  

                string str = wc.DownloadString("http://www.douban.com/group/topic/9493130/?start=100");

               MatchCollection ms= Regex.Matches(str, @"w+@(w+.)+w+");

               StringBuilder sb = new StringBuilder();

               foreach (Match item in ms)

               {

                   sb.AppendLine(item.Value);  

               }

               txtResult.Text = sb.ToString();

    输出结果为:

    字符串提取组

    01,用元括号分组

            02,使用Groups获得组集合

    首先正则表达式进行匹配提取的时候,按照所提供的“正则表达式”匹配到多个Match,同时Match包含了一个叫做组的概念。组针对一个匹配字符串而言,表示圆括号中的内容。组从左往右开始数,一次编号为1,2,3,使用时只用在groups中使用索引即可。

          现在回到刚开始的问题:

    192.168.1.100[port=8080,type=ftp]

    解析为:IP地址是...的服务器的...端口是打开的,提供的服务是...

      学过正则之后,再来看这个问题,就变得异常简单了。

    正则解决方案:

    string str = "192.168.1.100[port=8080,type=ftp]";

                Match match=Regex.Match(str,@"^(d{3}(.d{1,3}){3})[port=(d+),type=(w+)]$");

                if (match.Success)

                {

                    string result = string.Format("IP是{0},端口是{1},类型是{2}", match.Groups[1].Value, match.Groups[3].Value, match.Groups[4].Value);

                    MessageBox.Show(result);

                }

    怎么样,比之前的代码简单多了吧!这就是正则表达式的魅力所在。

    贪婪模式与非贪婪模式

    贪婪模式:从左到右尽可能多的匹配。

    C#中默认使用贪婪模式,取消贪婪模式使用?

    经验:一般开发的时候不用刻意去修饰为非贪婪模式,只有遇到bug的时候发现是贪婪模式的问题再去解决。如果匹配的结果比自己预想的要多,那么一般都是贪婪模式的原因。

    接下用一个案例简单看下贪婪模式

             string str = "123agb23424aa123agb23424aa";

                Match match = Regex.Match(str, @"((d+[a-z]+)+)?((d+[a-z]+)+)");

               MessageBox.Show(match.Groups[2].Value);

    如果不加?输出结果为123agb23424aa123agb

    加上?取消贪婪模式后输出结果为:123agb

  • 相关阅读:
    多线程篇七:通过Callable和Future获取线程池中单个务完成后的结果
    多线程篇六:线程池
    微服务学习和认识
    多线程篇五:多个线程访问共享对象和数据的方式
    多线程篇四:ThreadLocal实现线程范围内变量共享
    多线程篇三:线程同步
    多线程篇二:定时任务
    多线程篇一:传统线程实现方式
    Jms学习篇二:ActiveMQ
    04-运算符
  • 原文地址:https://www.cnblogs.com/woyipiaolingjiu/p/5176958.html
Copyright © 2020-2023  润新知