java - 为什么 (.*)* 进行两个匹配并且在 $1 组中没有选择任何内容?

标签 java .net regex perl language-agnostic

这源于对正则表达式语法形式化的讨论。我已经在几个正则表达式解析器中看到了这种行为,因此我将其标记为与语言无关。

采用以下表达式(根据您喜欢的语言进行调整):

replace("input", "(.*)*", "$1")

它将返回一个空字符串。为什么?

更奇怪的是,表达式 replace("input", "(.*)*", "A$1B") 将返回字符串 ABAB。为什么是双空匹配?

免责声明:我知道回溯和贪婪匹配,但Jeffrey Friedl 制定的规则似乎规定 .* 匹配所有内容,并且不进行进一步的回溯或匹配。那为什么$1是空的?

注意:与返回输入字符串的(.+)*进行比较。但是,http://regexhero.com显示仍然有两个匹配项,出于与上述相同的原因,这看起来很奇怪。

最佳答案

让我们看看会发生什么:

  1. (.*) 匹配 "input"
  2. "input" 被捕获到组 1 中。
  3. 正则表达式引擎现在位于字符串的末尾。但是由于 (.*) 重复了,所以会进行另一次匹配尝试:
  4. (.*) 匹配 "input" 之后的空字符串。
  5. 将空字符串捕获到组1中,覆盖“input”
  6. $1 现在包含空字符串。

评论中的一个好问题:

Then why does replace("input", "(input)*", "A$1B") return "AinputBAB"?

  1. (input)* 匹配 "input"。它被 "AinputB" 替换。
  2. (input)* 匹配空字符串。它被 "AB" 替换($1 为空,因为它没有参与比赛)。
  3. 结果:"AinputBAB"

关于java - 为什么 (.*)* 进行两个匹配并且在 $1 组中没有选择任何内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14500095/

相关文章:

java - WebView Android Null 异常

c# - 从 backgroundworker 获取错误值的进度

c# - 在以以下开头的同一行中查找多个正则表达式模式

c# - 为什么引用的 DLL 与 EXE 一起存储

c# - ASP.Net MVC 应用程序看似忽略数据库连接字符串

regex - 仅用于两位数月份和两位数日期的正则表达式

java - 两个字符之间的字符串的正则表达式

java - Android:组织方法显示警报对话框的最佳实践是什么

java - 如何在等待结束过程时真正显示 ProgressDialog

java - 有关如何从头开始设置非常简单的 J2EE Web 应用程序的教程?