美文网首页
正则表达式(Regular expression)

正则表达式(Regular expression)

作者: Jax_YD | 来源:发表于2021-02-24 14:20 被阅读0次

    正则表达式:是处理字符串的一种表达方式,提供了一种从一组字符串中选择特定字符串的机制
    POSIX规范定义了 UNIX 操作系统支持的功能,POSIX 规范的正则表达式有两种:

    • BRE (Basic Regular Expression) -- 基本型正则表达式
    • ERE (Extended Regular Expression) -- 扩展型正则表达式

    这里需要注意一点:正则表达式通配符没有任何关系,不是包含关系
    1、通配符Shell提供的功能
    2、正则表达式只是用来处理字符串


    下面我们来看一个常见的正则表达式,手机号码的判断:

    ^1[3-9](\d{9})$
    
    • ^:锚点操作符,匹配字符串的开头,这里紧跟着1表示以1开头的字符串
    • []:列表操作符,只匹配中括号中的一个字符
    • -:范围操作符,指定的范围。3-9表示范围在3和9之间
    • \d:代表0-9之间的数字
    • {}:间隔运算符,匹配前一个元素N次,这里表示匹配前一个元素9次
    • $锚点操作符,匹配字符串的结尾

    字符匹配

    • 我们先来看一些常见的字符
    字符 描述
    [ABC] 匹配[...]中的所有字符,例:[qaz]匹配字符串"Tiktok Byte Dance"中所有的q a z字母
    [^ABC] 匹配除了[...]中字符的所有字符,与 [ABC]相反
    [A-Z] [A-Z]表示一个区间,匹配所有大写字母,[a-z]表示所有小写字母
    . 匹配所有字符,除了\n \r和null(空字符),相当于[^\n\r]
    \w 匹配字母、数字、下划线。等价于[A-Za-z0-9]
    • 重复操作符
    字符 描述
    * 匹配前一个元素 0 次 或 多次
    + 匹配前一个元素 1 次 或 多次
    ? 匹配前一个元素 0 次 或 1次
    • 间隔操作符
    字符 描述
    {N} 匹配前一个元素 N 次,N是一个非负整数
    {min,} 匹配前一个元素至少 min 次,min是一个非负整数
    {min,max} 匹配前一个元素至少 min 次,至多 max 次;min和max均为非负整数注意逗号和两个数之间不能有空格
    • 列表操作符
      [...] & [^...]
      一般操作符在列表操作符里会失去特殊意义,除了:
    字符 描述
    ] 结束列表[]]
    \ 转义字符
    [: 字符类别操作符开始
    :] 字符类别操作符结束
    - 范围操作符,如0-9
    • 字符类别操作符
    字符 匹配类型 描述
    [:alnum:] [A-Za-z0-9] 匹配数字和字母
    [:alpha:] [A-Za-z] 匹配字母
    [:blank:] [\t] 匹配空格 和 Tab
    [:cntrl:] [\x00-\x1F\x7F] 匹配控制符
    [:digit:] [0-9] 匹配数字
    [:graph:] \x21-\x7E 匹配可视字符
    [:lower:] [a-z] 匹配小写字母
    [:print:] [\x20-\x7E] 匹配可视字符和空格
    [:punct:] ][!"#$%&'()*+,./:;<=>?@^_`{}·~-] 匹配标点符号
    [:space:] [\t\r\n\v\f] 空白字符
    [:upper:] [A-Z] 匹配大写字母字符
    [:xdigit:] [A-Fa-f0-9] 匹配十六进制字符
    • 特殊类别操作符
    字符 匹配类型 描述
    \w [:alnum:] 匹配数字和字母
    \d [:digit:] 匹配数字
    \W [^[:alnum:]] 匹配除了数字和字母
    \B [^[:digit:]] 匹配除了数字
    \< ^ 匹配字符串的开头
    \> $ 匹配字符串的结尾
    \b 匹配单词边界字符,to\b,但是不匹配tomorrow
    • 锚点操作符
    字符 描述
    ^ 匹配字符串的开头,需在开头
    $ 匹配字符串的结尾 或 换行符的前一个位置,需在结尾

    ⚠️ 注意:如果^在列表操作符中使用,并且在首位,代表取反

    操作符的优先级
    优先级(由高到低) 操作符
    归类相关的括号符号 [::]
    转义字符 \<特殊字符>
    括号表达 []
    分组 ()
    单字符重复 * + ? {m,n}
    串联 .
    锚点 ^ $
    备选 竖线(Markdown语法冲突,无法描述)

    贪婪模式、勉强模式、侵占模式

    贪婪匹配 勉强匹配 侵占匹配 描述
    X? X?? X?+ 匹配X零次或一次
    X* X*? X*+ 匹配X零次或多次
    X+ X+? X++ 匹配X一次或多次
    X{n} X{n}? X{n}+ 匹配Xn次
    X{n,} X{n,}? X{n,}+ 匹配X至少n次
    X{n,m} X{n,m}? X{n,m}+ 匹配X至少n次,但不超过m次
    贪婪模式

    例子:GoogleMaps

    • 模式:.*aps(贪婪模式) 由两部分组成
      1、p1(.*) :匹配方式为贪婪型
      2、p2(aps)
      匹配开始:
    • 第一轮:
      首先,p1会匹配字符串中的所有字符GoogleMaps,匹配成功;但是p2没有匹配字符,本轮匹配失败。
    • 第二轮:
      减少p1的匹配量,留出最后一个字符,那么此时存在两个字符串:s1代表GoogleMap / s2代表s。此时s1匹配p1,但是s2不匹配p2,本轮匹配失败。
    • 第三轮:
      继续减少p1的匹配量,留出两个字符,结果同第二轮一样。
    • 第四轮:
      再次减少p1的匹配量,字符串被分割成GoogleMaps两个部分,此时p1和p2都能匹配。返回匹配成功。
    勉强模式

    例子:GoogleMaps

    • 模式:.*?aps(勉强模式) 最小匹配方式,同样的分为两部分
      1、p1(.*?) :匹配方式为勉强模式
      2、p2(aps)
      匹配开始:
    • 第一轮:p1由于是0次和任意次,首次匹配0次;则直接用字符串去匹配p2,但是p2无法匹配字符,本轮匹配失败。
    • 第二轮:
      增加p1的匹配量,匹配G;此时存在两个字符串,s1代表G / s2代表oogleMaps,s1匹配p1,但是s2不匹配p2,本轮匹配失败。
      继续上述匹配,直到满足p2
    侵占模式

    例子:`GoogleMaps

    • 模式:.*+aps(侵占模式) ,同样的分为两部分
      1、p1(.*+) :匹配方式为勉强模式
      2、p2(aps)
      匹配开始时读入所有字符串,和p1匹配成功;但没有剩余字符串去和p2匹配,匹配失败。

    简单讲,贪婪模式和侵占模式相比,
    1、贪婪模式会在只有部分匹配成功的条件下,依次从多到少,减少匹配成功部分的匹配量,将字符留给其他部分去匹配
    2、而侵占模式则是占有所有能匹配成功的部分,绝不留给其他部分使用

    iOS中正则表达式的应用

    NSString *phoneNum = @"1384587921";
        NSError *error = NULL;
        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^1[3-9]([:digit:]{9})$" options:NSRegularExpressionCaseInsensitive error:&error];
        NSTextCheckingResult *result = [regex firstMatchInString:phoneNum options:0 range:NSMakeRange(0, [phoneNum length])];
        
        if (result) {
            NSLog(@"匹配成功");
        } else {
            NSLog(@"匹配失败");
        }
    

    ⚠️⚠️⚠️ 注意:正则表达式在不同的开发环境中是有所区别的,这一点需要在实际开发中灵活应用,比如:

    image.png
    在iOS的环境下,\d是不识别的。
    这是因为OC 和 Swift 都要求 转义文字字符串中的特殊字符(即:在它们前面加上反斜杠\)。反斜杠本身就是这样的特殊字符之一,由于用于创建正则表达式的模式也是字符串,因此会增加复杂性,因为在使用Stingand时需要转义反斜杠字符NSRegularWxpression。

    这也就意味着标准正则表达式\d,将以\\d的形式出现在Swift 或 OC 代码中。这一点大家要注意!

    ^1[3-9](\\d{9})$
    

    参考文档:正则表达式 - 语法

    相关文章

      网友评论

          本文标题:正则表达式(Regular expression)

          本文链接:https://www.haomeiwen.com/subject/jiarfltx.html