zoukankan      html  css  js  c++  java
  • Java正则表达中Greedy Reluctant Possessive 的区别

     

    Java正则表达中Greedy Reluctant Possessive 的区别

    分类: java
     

    目录(?)[+]

     

    上一篇文章《编程思想之正则表达式 》中讲了正则表达式的原理、使用方法和常见的正则表达式总结,本文将进一步探讨Java正则表达中Greedy、Reluctant、Possessive三种策略的区别。

    从Java的官方文档http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html中我们可以看到,正则表达式表示数量词的符号有三套,分别是Greedy(贪婪的)、Reluctant(勉强的)和Possessive(独占的)。其含意如下:

    Greedy 数量词

    X?

    X,一次或一次也没有

    X*

    X,零次或多次

    X+

    X,一次或多次

    X{n}

    X,恰好 n 次

    X{n,}

    X,至少 n 次

    X{n,m}

    X,至少 n 次,但是不超过 m 次

    Reluctant 数量词

    X??

    X,一次或一次也没有

    X*?

    X,零次或多次

    X+?

    X,一次或多次

    X{n}?

    X,恰好 n 次

    X{n,}?

    X,至少 n 次

    X{n,m}?

    X,至少 n 次,但是不超过 m 次

    Possessive 数量词

    X?+

    X,一次或一次也没有

    X*+

    X,零次或多次

    X++

    X,一次或多次

    X{n}+

    X,恰好 n 次

    X{n,}+

    X,至少 n 次

    X{n,m}+

    X,至少 n 次,但是不超过 m 次

    Greedy、Reluctant、Possessive的区别

    实例说话

    看上面的表格我们发现这三种数量词的含意都相同(如X?、X??、X?+都表示一次或一次也没有),但他们之间还是有一些细微的区别的。我们先来看一个例子:

    1.Greedy

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. public static void testGreedy() {  
    2.     Pattern p = Pattern.compile(".*foo");  
    3.     String strText = "xfooxxxxxxfoo";  
    4.     Matcher m = p.matcher(strText);  
    5.     while (m.find()) {  
    6.         System.out.println("matched form " + m.start() + " to " + m.end());  
    7.     }  
    8. }  
    结果:

    matched form 0 to 13

    2.Reluctant

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. public static void testReluctant() {  
    2.     Pattern p = Pattern.compile(".*?foo");  
    3.     String strText = "xfooxxxxxxfoo";  
    4.     Matcher m = p.matcher(strText);  
    5.     while (m.find()) {  
    6.         System.out.println("matched form " + m.start() + " to " + m.end());  
    7.     }  
    8. }  
    结果:

    matched form 0 to 4

    matched form 4 to 13

    3.Possessive

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. public static void testPossessive() {  
    2.     Pattern p = Pattern.compile(".*+foo");  
    3.     String strText = "xfooxxxxxxfoo";  
    4.     Matcher m = p.matcher(strText);  
    5.     while (m.find()) {  
    6.         System.out.println("matched form " + m.start() + " to " + m.end());  
    7.     }  
    8. }  
    结果:

    //未匹配成功

    原理讲解

    Greedy数量词被称为“贪婪的”是因为匹配器被强制要求第一次尝试匹配时读入整个输入串,如果第一次尝试匹配失败,则从后往前逐个字符地回退并尝试再次匹配,直到匹配成功或没有字符可回退。

    模式串:.*foo

    查找串:xfooxxxxxxfoo

    结果:matched form 0 to 13

    其比较过程如下

     


    Reluctant采用与Greedy相反的方法,它从输入串的首(字符)位置开始,在一次尝试匹配查找中只勉强地读一个字符,直到尝试完整个字符串。

    模式串:.*foo

    查找串:xfooxxxxxxfoo

    结果:matched form 0 to 4

          matched form 4 to 13

    其比较过程如下

     

    Possessive数量词总是读入整个输入串,尝试一次(仅且一次)匹配成功,不像Greedy,Possessive从不回退,即便这样做也可能使整体匹配成功。

    模式串:.*foo

    查找串:xfooxxxxxxfoo

    结果:

          //未匹配成功

    其比较过程如下

     

    参考文章:http://docs.oracle.com/javase/tutorial/essential/regex/quant.html

    再来看看几个例子:

    模式串:.+[0-9]

    查找串:abcd5aabb6

    结果:matched form 0 to 10

    模式串:.+?[0-9]

    查找串:abcd5aabb6

    结果:matched form 0 to 4

    模式串:.{1,9}+[0-9]

    查找串:abcd5aabb6

    结果:matched form 0 to 10

    模式串:.{1,10}+[0-9]

    查找串:abcd5aabb6

    结果:匹配失败

    如果您有什么疑惑和想法,请在评论处给予反馈,您的反馈就是最好的测评师!由于本人技术和能力有限,如果本博文有错误或不足之处,敬请谅解并给出您宝贵的建议!

    ========================欢迎关注编程思想系列文章========================

    编程思想之正则表达式

    编程思想之迭代器

    编程思想之递归

    编程思想之回调

  • 相关阅读:
    【转】 IntelliJ IDEA 详细图解最常用的配置 ,适合刚刚用的新人
    安装IntelliJ IDEA默认C盘文件过大怎么办
    [linux]netstat命令详解-显示linux中各种网络相关信息
    [linux]free命令详解-显示内存的使用情况
    用什么工具能找出性能瓶颈?
    [linux]iostat命令详解-监视系统输入输出设备和CPU的使用情况
    [linux]vmstat命令详解-显示虚拟内存状态
    好文章列表
    BigDecimal.setScale 处理java小数点
    Mybatis通用分页
  • 原文地址:https://www.cnblogs.com/01picker/p/4842105.html
Copyright © 2011-2022 走看看