贪婪、勉强和侵占量词间的不同
  在贪婪、勉强和侵占三个量词间有着细微的不同。
  贪婪(*, ?, +):读入整个串,从后往前匹配
  勉强(*?, ??, +?):从前往后匹配
  侵占(*+, ?+, ++):读入整个串,从前往后匹配,匹配的是整个串
  贪婪量词之所以称之为“贪婪的”,这是由于它们强迫匹配器读入(或者称之为吃掉)整个输入的字符串,来优先尝试第一次匹配,如果第一次尝试匹配(对于整个输入的字符串)失败,匹配器会通过回退整个字符串的一个字符再一次进行尝试,不断地进行处理直到找到一个匹配,或者左边没有更多的字符来用于回退了。赖于在表达式中使用的量词,最终它将尝试地靠着 1 或 0 个字符的匹配。
  但是,勉强量词采用相反的途径:从输入字符串的开始处开始,因此每次勉强地吞噬一个字符来寻找匹配,最终它们会尝试整个输入的字符串。
  最后,侵占量词始终是吞掉整个输入的字符串,尝试着一次(仅有一次)匹配。不像贪婪量词那样,侵占量词绝不会回退,即使这样做是允许全部的匹配成功。
  为了说明一下,看看输入的字符串是 xfooxxxxxxfoo 时。
Enter your regex: .*foo  // 贪婪量词
Enter input string to search: xfooxxxxxxfoo
I found the text "xfooxxxxxxfoo" starting at index 0 and ending at index 13.

Enter your regex: .*?foo  // 勉强量词
Enter input string to search: xfooxxxxxxfoo
I found the text "xfoo" starting at index 0 and ending at index 4.
I found the text "xxxxxxfoo" starting at index 4 and ending at index 13.

Enter your regex: .*+foo // 侵占量词
Enter input string to search: xfooxxxxxxfoo
No match found.
  第一个例子使用贪婪量词.*,寻找紧跟着字母“f”“o”“o”的“任何东西”零次或者多次。由于量词是贪婪的,表达式的.*部分第一次“吃掉”整个输入的字符串。在这一点,全部表达式不能成功地进行匹配,这是由于最后三个字母(“f”“o”“o”)已经被消耗掉了。那么匹配器会慢慢地每次回退一个字母,直到返还的“foo”在最右边出现,这时匹配成功并且搜索终止。
  然而,第二个例子采用勉强量词,因此通过首次消耗“什么也没有”作为开始。由于“foo”并没有出现在字符串的开始,它被强迫吞掉第一个字母(“x”),在 0 和 4 处触发了第一个匹配。测试用具会继续处理,直到输入的字符串耗尽为止。在 4 和 13 找到了另外一个匹配。
  第三个例子的量词是侵占,所以在寻找匹配时失败了。在这种情况下,整个输入的字符串被.*+消耗了,什么都没有剩下来满足表达式末尾的“foo”。
  你可以在想抓取所有的东西,且决不回退的情况下使用侵占量词,在这种匹配不是立即被发现的情况下,它将会优于等价的贪婪量词。


import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
public static void main(String[] args) {
String str = "<biao><>c<b>";
Pattern pattern;
Matcher matcher;
// 贪婪: 最长匹配 .* : 输出: <biao><>c<b>
pattern = Pattern.compile("<.*>");
matcher = pattern.matcher(str);
while (matcher.find()) {
System.out.println(matcher.group());
}
// 不知是否非贪婪 .*? : 输出: <biao>, <>, <b>
pattern = Pattern.compile("<.*?>");
matcher = pattern.matcher(str);
while (matcher.find()) {
System.out.println(matcher.group());
}
// 使用组, 输出<>里的内容, 输出: 'biao', ' ', 'b'
// 0组代表整个表达式, 子组从1开始
pattern = Pattern.compile("<(.*?)>");
matcher = pattern.matcher(str);
while (matcher.find()) {
System.out.println(matcher.group(1));
}
}
}
贪婪、勉强和侵占量词间的不同
  在贪婪、勉强和侵占三个量词间有着细微的不同。
  贪婪(*, ?, +):读入整个串,从后往前匹配
  勉强(*?, ??, +?):从前往后匹配
  侵占(*+, ?+, ++):读入整个串,从前往后匹配,匹配的是整个串
  贪婪量词之所以称之为“贪婪的”,这是由于它们强迫匹配器读入(或者称之为吃掉)整个输入的字符串,来优先尝试第一次匹配,如果第一次尝试匹配(对于整个输入的字符串)失败,匹配器会通过回退整个字符串的一个字符再一次进行尝试,不断地进行处理直到找到一个匹配,或者左边没有更多的字符来用于回退了。赖于在表达式中使用的量词,最终它将尝试地靠着 1 或 0 个字符的匹配。
  但是,勉强量词采用相反的途径:从输入字符串的开始处开始,因此每次勉强地吞噬一个字符来寻找匹配,最终它们会尝试整个输入的字符串。
  最后,侵占量词始终是吞掉整个输入的字符串,尝试着一次(仅有一次)匹配。不像贪婪量词那样,侵占量词绝不会回退,即使这样做是允许全部的匹配成功。
  为了说明一下,看看输入的字符串是 xfooxxxxxxfoo 时。
Enter your regex: .*foo  // 贪婪量词
Enter input string to search: xfooxxxxxxfoo
I found the text "xfooxxxxxxfoo" starting at index 0 and ending at index 13.

Enter your regex: .*?foo  // 勉强量词
Enter input string to search: xfooxxxxxxfoo
I found the text "xfoo" starting at index 0 and ending at index 4.
I found the text "xxxxxxfoo" starting at index 4 and ending at index 13.

Enter your regex: .*+foo // 侵占量词
Enter input string to search: xfooxxxxxxfoo
No match found.
  第一个例子使用贪婪量词.*,寻找紧跟着字母“f”“o”“o”的“任何东西”零次或者多次。由于量词是贪婪的,表达式的.*部分第一次“吃掉”整个输入的字符串。在这一点,全部表达式不能成功地进行匹配,这是由于最后三个字母(“f”“o”“o”)已经被消耗掉了。那么匹配器会慢慢地每次回退一个字母,直到返还的“foo”在最右边出现,这时匹配成功并且搜索终止。
  然而,第二个例子采用勉强量词,因此通过首次消耗“什么也没有”作为开始。由于“foo”并没有出现在字符串的开始,它被强迫吞掉第一个字母(“x”),在 0 和 4 处触发了第一个匹配。测试用具会继续处理,直到输入的字符串耗尽为止。在 4 和 13 找到了另外一个匹配。
  第三个例子的量词是侵占,所以在寻找匹配时失败了。在这种情况下,整个输入的字符串被.*+消耗了,什么都没有剩下来满足表达式末尾的“foo”。
  你可以在想抓取所有的东西,且决不回退的情况下使用侵占量词,在这种匹配不是立即被发现的情况下,它将会优于等价的贪婪量词。


import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
public static void main(String[] args) {
String str = "<biao><>c<b>";
Pattern pattern;
Matcher matcher;
// 贪婪: 最长匹配 .* : 输出: <biao><>c<b>
pattern = Pattern.compile("<.*>");
matcher = pattern.matcher(str);
while (matcher.find()) {
System.out.println(matcher.group());
}
// 不知是否非贪婪 .*? : 输出: <biao>, <>, <b>
pattern = Pattern.compile("<.*?>");
matcher = pattern.matcher(str);
while (matcher.find()) {
System.out.println(matcher.group());
}
// 使用组, 输出<>里的内容, 输出: 'biao', ' ', 'b'
// 0组代表整个表达式, 子组从1开始
pattern = Pattern.compile("<(.*?)>");
matcher = pattern.matcher(str);
while (matcher.find()) {
System.out.println(matcher.group(1));
}
}
}

java正则(贪婪、勉强)的更多相关文章

  1. java 正则 贪婪匹配 匹配sql语句中的引号内容

    public class Demo { public static void main(String[] args) { String sql1 = "use test;select * f ...

  2. JAVA 正则表达式的三种模式: 贪婪, 勉强和占有的讨论

    假设待处理的字符串是  xfooxxxxxxfoo 模式.*foo (贪婪模式): 模式分为子模式p1(.*)和子模式p2(foo)两个部分. 其中p1中的量词匹配方式使用默认方式(贪婪型). 匹配开 ...

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

    Java正则表达中Greedy Reluctant Possessive 的区别 分类: java2015-01-16 00:28 1280人阅读 评论(9) 收藏 举报 正则表达式Java   目录 ...

  4. Java正则速成秘籍(二)之心法篇

    导读 正则表达式是什么?有什么用? 正则表达式(Regular Expression)是一种文本规则,可以用来校验.查找.替换与规则匹配的文本. 又爱又恨的正则 正则表达式是一个强大的文本匹配工具,但 ...

  5. Java正则速成秘籍(一)之招式篇

    导读 正则表达式是什么?有什么用? 正则表达式(Regular Expression)是一种文本规则,可以用来校验.查找.替换与规则匹配的文本. 又爱又恨的正则 正则表达式是一个强大的文本匹配工具,但 ...

  6. Java正则速成秘籍(三)之见招拆招篇

    导读 正则表达式是什么?有什么用? 正则表达式(Regular Expression)是一种文本规则,可以用来校验.查找.替换与规则匹配的文本. 又爱又恨的正则 正则表达式是一个强大的文本匹配工具,但 ...

  7. java 正则匹配空格字符串 正则表达式截取字符串

    java 正则匹配空格字符串 正则表达式截取字符串 需求:从一堆sql中取出某些特定字符串: 比如配置的sql语句为:"company_code = @cc and project_id = ...

  8. url 中非法字符替换,java 正则替换

    url在传输时不允许的一些字符串,参考自:http://www.ietf.org/rfc/rfc1738.txt 以下字符用java正则替换为"_",一句话搞定: "{& ...

  9. 通用且常用的Java正则匹配工具,用以检查邮箱名、电话号码、用户密码、邮政编码等合法性

    一个通用且常用的Java正则匹配工具,用以检查邮箱名.电话号码.用户密码.邮政编码等合法性. import java.util.regex.Matcher; import java.util.rege ...

随机推荐

  1. Python 时间 time

    import time print time.strftime("%Y-%m-%d") import datetime print datetime.datetime.now() ...

  2. 68.ORM查询条件:date,time,year,week_day等

    1. date: 首先查看数据库中article表的信息,由表中的create_time字段可以看出时间为2020.2.5 打印出查询的结果: <QuerySet []>:但是查询的结果为 ...

  3. CTF -攻防世界-web高手区-mfw

    ---恢复内容开始--- 昂,我很菜这是网上大神的教程. https://blog.csdn.net/silence1_/article/details/89741733 ---恢复内容结束---

  4. List、Set和Map详解及其区别和他们分别适用的场景

    Java中的集合包括三大类 它们是Set(集).List(列表)和Map(映射),它们都处于java.util包中,Set.List和Map都是接口,它们有各自的实现类.Set的实现类主要有HashS ...

  5. 最大连续子序列和,以及开始、结束下标(HDU 1003)

    HDU1003 Problem Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the ...

  6. paddle(一)

    一.概述 一个机器学习的框架,提供了深度学习需要的神经网络,激活函数等主要功能. 基础概念 Program 一次模型训练就是一个program,通过执行器执行,默认环境下是执行fluid.defaul ...

  7. min25筛学习笔记

    min25筛简介:用来求积性函数F(x)前缀和的,复杂度O(n0.75/logn),大概能求n<=1010. 记一个数x的最小质因子为R(x),所以当x不为质数时,R(x)<=√x这是废话 ...

  8. 24.docker 部署 wordPress

    1. 拉取远程 mysql 和 wordpress 镜像 并 启动起来 使用 docker pull mysql:5.7.27 docker pull wordpress 2. 创建mysql 的 c ...

  9. git配置报错fatal: Authentication failed for ''问题解决

    如果在git配置中报错fatal: Authentication failed for '',其实就是凭证失败的意思 接着输入一下命令行没有出现要求输入用户名或密码,并报错 $ git config ...

  10. 黑马_10 Lucene:全文检索

    10 Lucene:01.全文检索基本介绍 10 Lucene:02.创建索引库和查询索引 10 Lucene:03.中文分析器 10 Lucene:04.索引库维护CURD