java regex possissive relunctant
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 regex possissive relunctant的更多相关文章
- java Regex
超全 http://www.rexegg.com/regex-lookarounds.html 这篇文章不错:http://www.cnblogs.com/lzq198754/p/5780340.ht ...
- Java Regex match IP address
Reference: [1] https://www.mkyong.com/regular-expressions/how-to-validate-ip-address-with-regular-ex ...
- 【总结】java regex 正则表达式 提取数字和去除数字,过滤数字,提取价格
@Test public void test33() { String phoneString = "哈哈,13888889999"; // 提取数字 Pattern patter ...
- 【Java.Regex】用正则表达式查找Java源文件中的注释
代码: package regex; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.I ...
- 【Java.Regex】用正则表达式查找Java文件里的字符串
代码: import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; imp ...
- 【Java.Regex】使用正则表达式查找一个Java类中的成员函数
代码: import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; imp ...
- java Regex匹配及解析文本
用一个main程序展示下 public static void main(String[] args){ String text = "SSM<br>LOC<b ...
- java中regex参考
在Sun的Java JDK 1.40版本中,Java自带了支持正则表达式的包,本文就抛砖引玉地介绍了如何使用java.util.regex包. 可粗略估计一下,除了偶尔用Linux的外,其他Linu ...
- [Android Tips] 21. Regex Named Groups in Android
Android SDK 并没有包含 Java 7 新增加的命名捕获组功能,需要使用第三方库 https://github.com/tony19/named-regexp import com.goog ...
随机推荐
- HDU 1248 寒冰王座
完全背包 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> ...
- CF 602B Approximating a Constant Range
(●'◡'●) #include<iostream> #include<cstdio> #include<cmath> #include<algorithm& ...
- 5. Java反射机制
Java反射机制 问题: 在运行时,对一个JAVA类,能否知道属性和方法:能否调用它的任意方法? 答案是可以的,JAVA提供一种反射机制可以实现. 目录 什么是JAVA的反射机制 JDK中提供的R ...
- java.net.NoRouteToHostException: No route to host
报错信息: java.net.NoRouteToHostException: No route to host at java.net.PlainSocketImpl.socketCon ...
- PHP中使用CURL(三)
对 post 提交的数据进行 http_build_query处理,然后再send出去,能实现更好的兼容性,更小的请求数据包. <?php /** * PHP发送Post数据 * @param ...
- LeetCode OJ 73. Set Matrix Zeroes
Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. click ...
- Chapter 14_4 使用_ENV
因为_ENV是一个普通的变量,我们可以像其他变量一样去对它进行赋值和访问. _ENV = nil 上面的赋值操作,将会使得在它之后的代码块不能直接访问全局变量.不过,对控制你的代码所使用的变量有用处. ...
- 解决curl中errno为51和60的错误
今天使用curl调用https接口的时候,发现接收不了数据 然后打印出curl_errno和curl_error发现是60错误,而生产环境是51错误 查了相关资料 加上两个参数就可以了 curl_se ...
- 深入体会__cdecl与__stdcall
在学习C++的过程中时常碰到WINAPI或者CALLBACK这样的调用约定,每每觉得十分迷惑.究竟这些东西有什么用?不用他们又会不会有问题?经过在网上的一番搜寻以及自己动手后,整理成以下的学习笔记.1 ...
- HDU 2722 Here We Go(relians) Again (spfa)
Here We Go(relians) Again Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/ ...