混淆正则表达式贪婪的运算符,并终止字符

时间:2011-11-22 20:38:04

标签: java regex scjp

我正在为SCJP考试做准备,以下模拟问题让我措手不及。工具中的解释并不是很好,所以我希望SO的知识渊博的人能够解释它。

使用C.*L的正则表达式,识别它将从CooLooLCuuLooC

中捕获的单词

我选择了CooL and CuuL。我选择这个选项的原因是因为我认为它会寻找C的起始匹配,然后将任意字符置零或更多次,直到找到L,然后终止。

然而,答案实际上是CooLooLCuuL。我很困惑前两个L如何通过?

有人可以帮我解决这个问题吗?

由于

3 个答案:

答案 0 :(得分:3)

还有一个可能有用的解释:

.*匹配任何内容(默认情况下除了换行符!!!!),零次或多次 - 一般情况下你理解这一点。但是,.*?也符合该定义。区别在于贪婪......

  • .*将匹配任何内容,直到它无法匹配任何其他内容('贪婪'或'渴望')
  • .*?将匹配任何内容,直到可以匹配以下表达式('非贪婪'或'不情愿')

因此,C.*L会找到一个大写C,然后将ooLooLCuuLooC.*匹配。然后它会发现它必须匹配大写L。位于字符串的末尾,这是不可能的,因此它可以与L匹配,迫使.*放弃字符LooC以便这样做。结果:CooLooLCuuL

如果您使用C.*?L,则会找到C,然后匹配o,测试下一个o以匹配L。这会失败,使其与oo匹配并测试下一个L以匹配L。这将成功,它将返回CooL

匹配CooLCuuL(即以C开头且以L结尾的任何字符串)的第三个选项是C[^L]*L。这与C匹配,然后匹配任何数量不是大写L的字符,然后是大写L

答案 1 :(得分:2)

C.*L匹配CooLooLCuuL,因为它很贪婪。它会尝试尽可能多地咀嚼,同时仍然找到一个匹配,直到找不到有效匹配的字符串左侧。 C.*?L非贪婪,因此匹配CooL,因为在找到第一个匹配时会满足。{1}}它甚至会留下足够的字符串,以便找到第二个匹配CuuL

答案 2 :(得分:2)

这是因为它是greedy search并且会匹配尽可能多的字符,然后回溯直到找到L字符。

这是获取更多信息的绝佳资源:http://www.regular-expressions.info/repeat.html