繁体   English   中英

正则表达式中的奇怪行为

[英]Strange behavior in regexes

有一个关于正则表达式的问题并试图回答我发现了另一个奇怪的事情。

String x = "X";
System.out.println(x.replaceAll("X*", "Y"));

这打印YY。 为什么??

String x = "X";
System.out.println(x.replaceAll("X*?", "Y"));

这打印YXY

为什么不情愿的正则表达式与'X'字符不匹配? "noting"X"nothing"但为什么第一个不匹配三个符号并匹配两个然后一个而不是三个? 和第二个正则表达式只匹配"nothing"而不是X

让我们依次考虑它们:

"X".replaceAll("X*", "Y")

有两场比赛:

  1. 在字符位置0处, X匹配,并用Y替换。
  2. 在字符位置1处,匹配空字符串,并将Y添加到输出中。

最终结果: YY

"X".replaceAll("X*?", "Y")

还有两场比赛:

  1. 在字符位置0处,匹配空字符串,并将Y添加到输出中。 此位置的字符X未被匹配消耗,因此逐字复制到输出中。
  2. 在字符位置1处,匹配空字符串,并将Y添加到输出中。

最终结果: YXY

*是一个棘手的'量词',因为它意味着'0或更多'。 因此,它也匹配'0倍X'(即空字符串)。

我会用

"X".replaceAll("X+", "Y")

具有预期的行为。

在您的第一个示例中,您使用的是“贪婪”量词。 这意味着在尝试第一次匹配之前强制读取输入字符串,因此尝试的第一个匹配是整个输入。 如果输入匹配,匹配器将超过输入字符串并在字符串末尾执行零长度匹配,因此您看到两个匹配项。 贪婪的匹配器在第一次匹配尝试成功之前的字符X之前永远不会退回到零长度匹配。

在第二个例子中,您使用的是“不情愿”量词,与“贪婪”相反。 它从头开始,并尝试在前进时匹配一个角色(如果必须)。 因此匹配“X”字符之前的零长度匹配,匹配器向前移动一个(这就是为什么你仍然在输出中看到“X”字符),其中下一个匹配现在是“X”之后的零长度匹配”。
这里有一个很好的教程: http//docs.oracle.com/javase/tutorial/essential/regex/quant.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM