zoukankan      html  css  js  c++  java
  • java regex possissive relunctant

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

    分类: java

    目录(?)[+]

     

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

    从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 次

    GreedyReluctantPossessive的区别

    实例说话

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

    1.Greedy

    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

    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

    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数量词总是读入整个输入串,尝试一次(仅且一次)匹配成功,不像GreedyPossessive从不回退,即便这样做也可能使整体匹配成功。

    模式串:.*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

    结果:匹配失败

     

  • 相关阅读:
    Hashcode的作用
    java 强弱软虚 四种引用,以及用到的场景
    Object类有哪些公用方法?
    equals和==的区别
    switch能否用string做参数
    Java九种基本数据类型,以及他们的封装类
    Singleton(Java)
    快速排序和二分查找(Javascript)
    快速排序和二分查找(Go)
    ubuntn 安装 MySQL
  • 原文地址:https://www.cnblogs.com/jvava/p/4977650.html
Copyright © 2011-2022 走看看