zoukankan      html  css  js  c++  java
  • 正则表达式初探

    本章主要想和大家分享下正则表达式的一些基础用法,希望能够对一些小白有所帮助,也为了防止自己以后遗忘相关知识点,下面我们正式进入主题。

    一、正则表达式

      1、正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式。
      2、正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
      3、在编写处理字符串的程序或网页时,经常会有查找或替换符合某些复杂规则的字符串的需要。
      4、正则表达式就是记录文本规则的代码。

      作用:
        1、查找数据
        2、替换数据

      正则表达式能做什么(字符串的匹配、字符串的提取、字符串的替换

    二、正则表达式的构成

      1、普通字符(如果直接写多个普通字符,则会被当做一个整体的字符串来匹配)

        这包括所有的大小写字母字符,所有数字,所有标点符号以及一些特殊符号。
        例如:Hello world xyh666

      2、定义字符集(取值范围(该点都是匹配单个字符,要想匹配字符串需要结合限定符来实现)
        [a-e] 表示a到e这些字符中的某一个字符
        [aeiou] 表示aeiou这5个字符其中的某一个字符
        [a-zA-Z] 表示大写、小写字母中的某一个字符
        [0-9] 表示0到9之间某一个数字

        代表非
        [^lsjd]  :不是中括号中的任意一个字符
        [^a-f]  :a-f范围外的任意一个字符

      3、组合字符(大写表示非)(该点都是匹配单个字符,要想匹配字符串需要结合限定符来实现)

        d  :匹配一个数字字符。等价于[0-9]。
        D  :匹配一个非数字字符。等价于[^0-9]。
        w  :匹配一个字母或一个数字或一个下划线或一个汉字。
        W  :匹配一个非字母、非数字、非下划线和非汉字的字符。
        s  :匹配一个任意的空白符,包括空格、制表符、换页符等等。等价于[ f v]。
        S  :匹配任意一个非空白符。等价于[^ f v]。
         :匹配单词的开始或结束的位置。
        B  :匹配不是单词开头或结束的位置。

      4、特殊字符

        $  :表示字符串的结尾位置(以什么结尾)
         :表示字符串的开始位置(以什么开始)(在取值范围中还表示非)
         :一个点表示匹配一个除换行符 之外的任何单字符(匹配单个字符,要想匹配字符串需要结合限定符来实现)
        或者的意思,指明两项之间的一个选择 与[...]类似
          :这个符号是用来转义
        ( ) 分组,标记一个子表达式的开始和结束位置

      5、常用限定符
        =================匹配次数=================
        {m}  :其前一单元严格出现m次(重复m次)
        {m,}  :其前一单元出现至少m次(重复m次或更多次)
        {m,n}  :其前一单元出现至少m次,最多n次(重复m到n次)
        =======================================
        =================多次匹配=================
          :其前面那个单元出现0次或任意次数(重复零次或更多次)
          : 其前面那个单元出现1次或1次以上 至少匹配一次(重复一次或更多次)
        ?  : 其前面那个单元出现0次或1次(重复零次或一次)懒惰匹配(尽可能短匹配)
        =======================================
      6、贪婪与懒惰(贪婪模式和非贪婪模式)(尽可能长匹配和尽可能短匹配)
        *? 重复任意次,但尽可能少重复
        +? 重复1次或更多次,但尽可能少重复
        ?? 重复0次或1次,但尽可能少重复
        {n,m}? 重复n到m次,但尽可能少重复
        {n,}? 重复n次以上,但尽可能少重复

      7、分组

        当用()定义了一个正则表达式组后,正则引擎则会把被匹配的组按照顺序编号,存入缓存。

        默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。

        我们可以通过“数字”的方式进行引用已经存入缓存的组。1引用第一个匹配的组,2引用第二个组,以此类推。

        括号内的内容会被当成一个整体进行匹配。

      8、非获取匹配和预查(零宽断言)

        非获取匹配:是指正则引擎不会把被匹配的组存入缓存,我们也无法通过“数字”的方式进行引用我们的组。

        预查预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。(即用来预查的表达式字符串不会被消耗,它只是用于指定一个位置

        零宽断言:用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。

        ===========================================================================================

        (?=exp)也叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式exp。比如w+(?=ing),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc。

        (?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。比如(?<=re)w+会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。

        ===========================================================================================

        (?:pattern) 非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分时很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。

        (?=pattern) 非获取匹配,正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。

        (?!pattern) 非获取匹配,正向否定预,在任何不匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。

        (?<=pattern) 非获取匹配,反向肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。

        (?<!patte_n) 非获取匹配,反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。

      9、其他常用正则匹配

        匹配中文字符的正则表达式:[u4e00-u9fa5]

        匹配双字节字符(包括汉字在内):[^x00-xff]

        匹配中文、英文字母和数字及_:^[u4e00-u9fa5_a-zA-Z0-9]+$[u4e00-u9fa5_a-zA-Z0-9_]{4,10}

        只含有汉字、数字、字母、下划线并且不能以下划线开头和结尾:^(?!_)(?!.*?_$)[a-zA-Z0-9_u4e00-u9fa5]+$

        (?!_)表示不能以_开头,(?!.*?_$)表示不能以_结尾

    三、C#代码调用正则表达式

        命名空间 System.Text.RegularExpressions
        
        1new Regex(正则表达式).IsMatch(要匹配的字符串)   返回bool
        2、Regex.Match
            Match match = Regex.Match("age=30", @"^(.+)=(.+)$");
            if (match.Success)
            {
                Console.WriteLine(match.Groups[0].Value);//第0组 输出完整的字符串 age=30
                Console.WriteLine(match.Groups[1].Value);//第1组 age
                Console.WriteLine(match.Groups[2].Value);//第2组 30
            }
        3、Regex.Matches
            StringBuilder sb = new StringBuilder();
            sb.Append("<Name>张三</Name>
    <Name>李四</Name>
    <Name>王五</Name>");
    
            MatchCollection mc = Regex.Matches(sb.ToString(), @"(?<=<Name>).*(?=</Name>)");
            foreach (Match m in mc)
            {
                Console.WriteLine(m.Value);
            }

    四、示例说明

    接下来针对第二大点的内容我们举些例子来说明:

    示例1(普通字符):

    我们用 xyh 来匹配 xyh123 如下图所示:

     从上面的正则表达式测试器匹配的结果可以看出:如果直接写多个普通字符,则会被当做一个整体的字符串来匹配。

    示例2(元字符和限定符):

    我们用 d 来匹配 xyh123 如下图所示:

     从匹配的结果可以发现d只是匹配单个数字,所以有三个结果,分别为1、2、3,那如果想匹配一整个字符串123要怎么办呢?此时就要结合限定符来实现了。继续来看下下面的一张图。

     从图中可以看出结合限定符后就可以实现匹配到123这个字符串了。

    示例3(普通字符和元字符组合):

    我们用 https://www..+.com 来匹配这么一句话:https://www.jd.com两个链接https://www.taobao.com  如下图所示:

     可以发现匹配的结果为完整的一整句话,那为什么不是匹配出2个结果分别为 https://www.jd.com 和 https://www.taobao.com 呢?

     那是因为默认情况下正则表达式采用贪婪模式匹配(即尽可能多匹配),所以匹配出了完整的一句话,此时可以用?来实现非贪婪模式匹配(即尽可能少匹配),如下图所示:

     这样就匹配出了2个结果

    示例4(分组):

     我们用 (abc)1 来匹配 abcabc666 如下图所示:

     从图中可以看出匹配结果为abcabc,为什么会是这样呢?首先我们分组(abc)匹配到存入缓存中的值为abc,通过1的方式就取到了存入缓存中的第1个分组值abc,这个分组值abc与原来分组(abc)匹配到的字符串abc组成新的匹配字符串abcabc,用新的匹配字符串abcabc去匹配abcabc666得到的匹配结果就是abcabc了。

    示例5(非获取匹配):

    非获取匹配(?:pattern)如下图所示:

     从图中可以看出非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用。因此无法通过“数字”的方式来获取。

    示例6(预查和零宽断言):

    预查不消耗字符,它只是用于指定一个位置,如下图所示:

     从图中可以看出用 ab(?=a) 来匹配 ababa123 时会得到两个结果而不是一个结果,那是因为预查不消耗字符(即不会消耗用来预查用的表达式exp对应的字符),它只是用于指定一个位置,所以在第3个位置的a(即第2个a)没有被消耗掉。当匹配到第1个结果ab后会从第3个位置的a(即第2个a)开始查找下一个能匹配的字符串,而不是从第4个位置的b(即第2个b)开始查找,这就解释了为什么会匹配到2个结果了。

    PS:本文仅是个人见解 ,如有表述错误欢迎评论指正!

    正则表达式测试器:

    链接:https://pan.baidu.com/s/1CwyrLH2dwbBk1KVi2FCGDw 
    提取码:nwyc

     

    版权声明:本文部分描述摘自网络,如有雷同纯属巧合,如有侵权请及时联系本人修改,谢谢!!!

  • 相关阅读:
    [LeetCode] Power of Three 判断3的次方数
    [LeetCode] 322. Coin Change 硬币找零
    [LeetCode] 321. Create Maximum Number 创建最大数
    ITK 3.20.1 VS2010 Configuration 配置
    VTK 5.10.1 VS2010 Configuration 配置
    FLTK 1.3.3 MinGW 4.9.1 Configuration 配置
    FLTK 1.1.10 VS2010 Configuration 配置
    Inheritance, Association, Aggregation, and Composition 类的继承,关联,聚合和组合的区别
    [LeetCode] Bulb Switcher 灯泡开关
    [LeetCode] Maximum Product of Word Lengths 单词长度的最大积
  • 原文地址:https://www.cnblogs.com/xyh9039/p/11780032.html
Copyright © 2011-2022 走看看