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正则替换为"_",一句话搞定: "{& ...
随机推荐
- python学习【第四篇】python函数 (一)
一.函数的介绍 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可以 ...
- 2016-06-19 NOIP模拟赛
2016-06-19 NOIP模拟赛 by coolyangzc 共3道题目,时间3小时 题目名 高级打字机 不等数列 经营与开发 源文件 type.cpp/c/pas num.cpp/c ...
- <2013 07 22> 游历西欧
从本月11号开始到昨天,10天时间,和其他六位同学畅游了西欧,路经慕尼黑-巴塞罗马-尼斯-马赛-巴黎-阿姆斯特丹,最后回到慕尼黑,每个地方都待了两天,参观了主要的景点和建筑,见识了本地文化与饮食. 令 ...
- 类 Stack<E>
Stack类 Stack 类表示后进先出(LIFO)的对象堆栈.它通过五个操作对类 Vector 进行了扩展 ,允许将向量视为堆栈. 它提供了通常的 push 和 pop 操作,以及取堆栈顶点的 pe ...
- Linux安装配置
虚拟机配置Linux镜像文件 配置网路 防火墙 一.虚拟机配置Linux镜像文件 1.将下载好的Linux镜像文件载入进来 2.启动虚拟机,安装 3.此步为是否检测linux系统,我们选择" ...
- KGX滚动分页源码
源码描述: 本工具采用Jquery框架,通过jquery调用ashx获取并输出数据,示例中采用测试数据,可以自行扩展为图片等等 当下流行的分页方式,鼠标滚动下拉条会自动展示下一页信息,类似瀑布流的效果 ...
- redis3.2.11多机多实例集群部署及测试连接情况
机器配置 redis3.2.11安装配置规划 机器 192.168.169.136(本机虚拟机1) 192.168.169.137(本机虚拟机2) 系统 Red Hat Enterprise Linu ...
- PyQt4打包exe文件
使用到工具pyinstaller pip install pyinstaller 使用指令打包,其中xxx.ico为需要的图标,xxx.py为要打包的py文件 pyinstaller -w --ico ...
- ACM解题之(ZOJ 2724)Windows Message Queue
题目来源: 点击打开链接 题目翻译: 消息队列是windows系统的基本基础.对于每个进程,系统都维护一个消息队列.如果这个过程发生某些事情,例如鼠标点击,文本改变,系统会向队列添加一条消息.同时,如 ...
- Ubuntu 下 java 版本的切换
切换的方法很简单,使用下面的两个命令即可: update-alternatives --config java update-alternatives --config javac eg: root@ ...