Java正则表达中Greedy Reluctant Possessive 的区别
上一篇文章《编程思想之正则表达式 》中讲了正则表达式的原理、使用方法和常见的正则表达式总结,本文将进一步探讨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
- public static void testGreedy() {
- Pattern p = Pattern.compile(".*foo");
- String strText = "xfooxxxxxxfoo";
- Matcher m = p.matcher(strText);
- while (m.find()) {
- System.out.println("matched form " + m.start() + " to " + m.end());
- }
- }
结果:
matched form 0 to 13
2.Reluctant
- public static void testReluctant() {
- Pattern p = Pattern.compile(".*?foo");
- String strText = "xfooxxxxxxfoo";
- Matcher m = p.matcher(strText);
- while (m.find()) {
- System.out.println("matched form " + m.start() + " to " + m.end());
- }
- }
结果:
matched form 0 to 4
matched form 4 to 13
3.Possessive
- public static void testPossessive() {
- Pattern p = Pattern.compile(".*+foo");
- String strText = "xfooxxxxxxfoo";
- Matcher m = p.matcher(strText);
- while (m.find()) {
- System.out.println("matched form " + m.start() + " to " + m.end());
- }
- }
结果:
//未匹配成功
原理讲解
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
结果:匹配失败
如果您有什么疑惑和想法,请在评论处给予反馈,您的反馈就是最好的测评师!由于本人技术和能力有限,如果本博文有错误或不足之处,敬请谅解并给出您宝贵的建议!
========================欢迎关注编程思想系列文章========================
Java正则表达中Greedy Reluctant Possessive 的区别的更多相关文章
- 浅谈Java和JavaScript中变量和数据类型的区别
对于一门编程语言的学习,如果第一步是安装环境,那么第二步一定是学习这门语言的基本规则,变量和数据类型则首当其冲 JavaScipt作为一个蹭Java热度而命名的语言,在很多方面和Java也有一定的相似 ...
- java.util包中 Set 和 List 的区别
http://ligaosong.iteye.com/blog/903692 对于Set 和 List都是 接口 Collection 的子接口 1.Set 不允许重复,List允许重复 2.Set ...
- java集合框架中Set和List的区别
1. Set 接口实例存储的是无序的,不重复的数据.List 接口实例存储的是有序的,可以重复的元素. 2. Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有Ha ...
- java.io.PrintWriter 中 write() 与 print() 的区别
最终都是重写了抽象类Writer里面的write方法print方法可以将各种类型的数据转换成字符串的形式输出.重载的write方法只能输出字符.字符数组.字符串等与字符相关的数据.
- java实际项目中interface和abstract interface 区别
参考:https://zhidao.baidu.com/question/424485344260391052.html 这2种有什么区别,根据实际项目经验 帮我解答下 谢谢啊~~~~~~~~~问题补 ...
- JS写法 数值与字符串的相互转换 取字符中的一部分显示 正则表达规则
http://www.imooc.com/article/15885 正则表达规则 <script type="text/javascript"> </scrip ...
- Java正则中为什么反斜线"\"需要用“\\\\”表示,原因详解。
首先,我们需要知道在java字符串和正则表达式中,“\”都具有特殊的含义. 一.在Java的字符串中"\"有两个功能 (一)代表特殊字符:\t代表制表符,\n代表换行....等. ...
- php 正则表达示中的原子
原子 原子是正则表达示里面的最小单位,原子说白了就是需要匹配的内容.一个成立的正则表达示当中必须最少要有一个原子.大理石平台精度等级 所有可见不可见的字符就是原子 说明:我们见到的空格.回车.换行.0 ...
- url 中非法字符替换,java 正则替换
url在传输时不允许的一些字符串,参考自:http://www.ietf.org/rfc/rfc1738.txt 以下字符用java正则替换为"_",一句话搞定: "{& ...
随机推荐
- 初探webpack之环境配置
先感叹一句,前端的发展真是太快了,ng和bb还没怎么学好就要过时了.现在感觉react当是未来的一个大方向. 以前一直用的grunt,不过前段时间作者已经停止更新了.正好webpack风头正盛,咱也不 ...
- Python之可迭代对象、迭代器、生成器
在使用Python的过程中,很容易混淆如下几个关联的概念: 1.容器(container) 2.可迭代对象(Iterable) 3.迭代器(Iterator) 4.生成器(generator) 5.生 ...
- 20160916-3:mysql主从复制
一.什么是主从复制 将一个数据库节点的数据拷贝到一个或多个数据库节点(主节点—>从节点) 二.主从复制的原理 [简述]:将主节点上的变更操作存储到binlog,从节点建立了到主节点的复制关系后, ...
- SpringBoot整合Dubbo报错: java.lang.ClassCastException
com.alibaba.dubbo.rpc.RpcException: Failed to invoke remote proxy method queryGoodsLimitPage to regi ...
- <2013 10 18> Linux随机数生成器可能确实存在安全弱点
生成随机数是密码学中的一项基本任务,是生成加密密钥和加密算法或加密协议所必不可少的.理想中的随机数是完美的,但实践中的随机数都是用伪随机数生成器(PRNG)生成,随机数的质量对安全性至关重要.安全专家 ...
- <2013 08 27> 雅思阅读相关
1.雅思阅读的总体难度不大,但是时间较紧,三段较长的阅读材料和40个题目,总耗时60min.基本上前两个材料可以花15~20min,最后一个材料至少花20min完成. 2.阅读的技巧在于三点:其一,先 ...
- Django模型中OneToOneField和ForeignKey的区别
网上看到一篇讲解"Django模型中OneToOneField和ForeignKey区别" 的文章,浅显易懂; 可以把ForeignKey形象的类比为: ForeignKey是on ...
- SAP后勤模块实施攻略——1.ERP和SAP
近日接到任务,看完乐立骏老师的SAP后勤模块实施攻略这本书,现在把第一章内容简单整理.第一章讲的是关于ERP和SAP的介绍. 1.ERP E:Enterprise / 企业 R:Resource / ...
- Spring学习笔记4—流程(Spring Web Flow)
Spring Web Flow是Spring框架的子项目,作用是让程序按规定流程运行. 1 安装配置Spring Web Flow 虽然Spring Web Flow是Spring框架的子项目,但它并 ...
- gradle build 找不到tools.jar 解决方法
import javax.tools.ToolProvider compile(files(((URLClassLoader) ToolProvider.getSystemToolClassLoade ...