技术控

    今日:0| 主题:63445
收藏本版 (1)
最新软件应用技术尽在掌握

[其他] Java正则表达中Greedy Reluctant Possessive 的区别

[复制链接]
深流Penetrasunny 发表于 2016-10-12 07:02:26
208 2
上一篇文章《 编程思想之正则表达式 》中讲了正则表达式的原理、使用方法和常见的正则表达式总结,本文将进一步探讨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

  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
  其比较过程如下
   

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

Java正则表达中Greedy Reluctant Possessive 的区别
Reluctant采用与Greedy相反的方法,它从输入串的首(字符)位置开始,在一次尝试匹配查找中只勉强地读一个字符,直到尝试完整个字符串。
  模式串:.*foo
  查找串:xfooxxxxxxfoo
  结果:matched form 0 to 4
  matched form 4 to 13
  其比较过程如下
   

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

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

  Possessive数量词总是读入整个输入串,尝试一次(仅且一次)匹配成功,不像Greedy,Possessive从不回退,即便这样做也可能使整体匹配成功。
  模式串:.*foo
  查找串:xfooxxxxxxfoo
  结果:
  //未匹配成功
  其比较过程如下
   

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

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

   参考文章: 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
  结果:匹配失败
  如果您有什么疑惑和想法,请在评论处给予反馈,您的反馈就是最好的测评师!由于本人技术和能力有限,如果本博文有错误或不足之处,敬请谅解并给出您宝贵的建议!
靖巧 发表于 2016-10-13 02:43:23
帮顶个帖,攒人品,说不定我就会升职加薪、当上总经理、出任CEO、迎娶白富美、走上人生巅峰,嘿嘿,想想还有点小激动。
回复 支持 反对

使用道具 举报

ygiun 发表于 2016-11-21 17:24:40
OMG!介是啥东东!!!
回复 支持 反对

使用道具 举报

我要投稿

推荐阅读


回页顶回复上一篇下一篇回列表
手机版/c.CoLaBug.com ( 粤ICP备05003221号 | 粤公网安备 44010402000842号 )

© 2001-2017 Comsenz Inc.

返回顶部 返回列表