【问题标题】:How to precisely identify & work greedy or reluctant quantifiers? [duplicate]如何准确识别和处理贪婪或不情愿的量词? [复制]
【发布时间】:2013-06-04 09:49:45
【问题描述】:

给定:

import java.util.regex.*;

class Regex2 {    
  public static void main (String args[]) {
    Pattern p = Pattern.compile(args[0]);
    Matcher m = p.matcher (args [1]);    
    boolean b = false;

    while (m. find()) {
       System.out.print(m.start()  + m.group());
    }
  }
}

命令行表达式为:

java Regex2 "\d*" ab34ef

结果如何?

A. 234
B. 334
C. 2334
D 0123456
E. 01234456
F. 12334567
G. Compilation fails

SCJP 的书对正则表达式、模式和匹配器的解释如此可怕,令人难以置信。 无论如何,我非常了解大部分基础知识,并查看了有关贪婪和不情愿量词的 Sun/Oracle 文档。我理解这些概念,但对一些事情有点模糊:

“贪婪”量词的物理符号究竟是什么?它只是一个*,吗?或 + ? 如果是这样,有人可以根据本书详细解释这个答案如何变成E吗?当我自己运行它时,我得到了答案:2334!

在这里我们会使用一个贪婪的量词,对吗?这将消耗整个字符串,然后回溯并连续查找零个或多个数字。因此,如果贪心,“完整字符串”将连续包含 2 个数字,并且仅执行一次 .find() (即 m.start = 0 , m.group = "ab34ef"),根据该定义!

感谢大家的帮助。

【问题讨论】:

  • 无法判断甚至无法编译的 Java 代码的运行时行为。请修复您的代码。
  • 抱歉,Marko,已解决。

标签: java regex scjp quantifiers


【解决方案1】:

这些是\d*"ab34ef" 的比赛:

  • 索引 0:零宽度;
  • 索引 1:零宽度;
  • 索引 2:“34”;
  • 索引 4:零宽度;
  • 索引 5:零宽度;
  • 索引 6:零宽度。

这应该可以解释您的输出。如果量词不情愿,这将是不同的:

  • 索引 2:零宽度;
  • 索引 3:零宽度;

勉强的量词尽可能少地抓取以使整个表达式匹配。

【讨论】:

  • 感谢 Marko,它告诉我我们如何获得输出。为什么不将它用作贪婪的量词,这是我的问题!
  • 对不起,我完全不明白贪婪和不情愿之间的区别?你能详细说明吗?为什么不先将整个输入字符串作为一个整体,因为它是贪婪的,因此在输入字符串中找到2位并立即返回?或者如果它需要尾随数字,为什么不从最后两个字母回溯并在字符串 ab34 上输入零?
  • * 量词匹配零个或多个个字符。因此,每个索引都有一个匹配项。
  • 是的,但是根据我的准备,单个 * 是一个贪婪的匹配器。 *+ 是不情愿的。所以 *+ 应该给我输出 01234456 - 它确实如此,我已经测试过了。然而,简单地使用 * 应该会有所不同,即。以一种贪婪的方式!
  • 不,*? 是不情愿的。 *+ 将是 占有 量词,这是完全不同的东西。
猜你喜欢
  • 1970-01-01
  • 2014-06-21
  • 1970-01-01
  • 2021-02-09
  • 1970-01-01
  • 2023-01-16
  • 1970-01-01
  • 1970-01-01
  • 2010-11-09
相关资源
最近更新 更多