• JAVA 正则表达式的三种模式: 贪婪, 勉强和占有的讨论


    假设待处理的字符串是  xfooxxxxxxfoo

        模式.*foo (贪婪模式): 

    模式分为子模式p1(.*)和子模式p2(foo)两个部分. 其中p1中的量词匹配方式使用默认方式(贪婪型)。 

    匹配开始时,吃入所有字符xfooxxxxxx去匹配子模式p1。匹配成功,但这样以来就没有了字符串去匹配子模式p2。本轮匹配失败;第二轮:减少p1部分的匹配量,吐出最后一个字符, 把字符串分割成xfooxxxxxxfo和o两个子字符串s1和s2。 s1匹配p1, 但s2不匹配p2。本轮匹配失败;第三轮,再次减少p1部分匹配量,吐出两个字符, 字符串被分割成xfooxxxxxxfo和oo两部分。结果同上。第四轮,再次减少p1匹配量, 字符串分割成xfooxxxxxx和foo两个部分, 这次s1/s2分别和p1/p2匹配。停止尝试,返回匹配成功。


        模式.*?foo (勉强模式): 最小匹配方式。

    第一次尝试匹配, p1由于是0或任意次,因此被忽略,用字符串去匹配p2,失败;第二次,读入第一个字符x, 尝试和p1匹配, 匹配成功; 字符串剩余部分fooxxxxxxfoo中前三个字符和p2也是匹配的. 因此, 停止尝试, 返回匹配成功。在这种模式下,如果对剩余字符串继续去寻找和模式相匹配的子字符串,还会找到字符串末尾的另一个xfoo,而在贪婪模式下,由于第一次匹配成功的子串就已经是所有字符,因此不存在第二个匹配子串。


        模式.*+foo (侵占模式): 也叫占用模式。

    匹配开始时读入所有字符串, 和p1匹配成功, 但没有剩余字符串去和p2匹配。因此, 匹配失败。返回。

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

    再看下面一个例子:贪婪模式与侵占模式的比较
    正则:w+[a-z]与w++[a-z]
    目标串:232hjdhfd7474$
    分析:①w+[a-z]:w+属于贪婪模式,会一次性吃掉它所能吃掉的所有的字符,也就是子串232hjdhfd7474,此时[a-z]不能够找到匹配了,故w+匹配的串会吐出一个字符4,但此时还是得不到匹配。反复的这样吐出回退,直到吐出字符d时,此时[a-z]能够匹配h,所以这时正则表达式会返回一次成功的匹配结果,为232hjdhfd
    ②w++[a-z]:w++属于侵占模式,它会一次性吃掉它所能够吃掉的所有字符,即子串232hjdhfd7474,而且不留给其他部分使用,故不会回退。此时[a-z]不能够找到匹配,所以此次匹配失败。在余下的子串中也找不到能匹配成功的子串。所以整个正则表达式是找不到匹配结果的!

    量 词 种 类 意  义
    贪婪 勉强 侵占
    X? X?? X?+ 匹配 X 零次或一次
    X* X*? X*+ 匹配 X 零次或多次
    X+ X+? X++ 匹配 X 一次或多次
    X{n} X{n}? X{n}+ 匹配 X n 次(这个应该不存在这几种模式,就是固定匹配n个)
    X{n,} X{n,}? X{n,}+ 匹配 X 至少 n 次
    X{n,m} X{n,m}? X{n,m}+ 匹配 X 至少 n 次,但不多于 m 次
  • 相关阅读:
    Maven属性
    安居客Android项目架构演进
    HttpClient 解说 (1) 基础
    linux 打包和压缩文件
    java AES-256加解密解决方法
    jdk8 分隔字符串最新方法
    springboot 过滤器,拦截器,切片的运用
    thinkphp 5.0手记
    如何使用UDP进行跨网段广播
    php multicast多播实现详解
  • 原文地址:https://www.cnblogs.com/xiaohanlin/p/7818506.html
Copyright © 2020-2023  润新知