为什么 (.*)* 进行两次匹配,而在 $1 组中不选择任何内容?

2022-09-02 04:00:42

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

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

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

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

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

免責聲明:我知道回溯和贪婪的比赛,但杰弗里·弗里德尔制定的规则似乎决定了一切匹配,并且没有进一步的回溯或匹配。那么为什么是空的呢?.*$1

注意:比较 与 ,返回输入字符串。但是,http://regexhero.com 显示仍然有两场比赛,由于与上述相同的原因,这似乎很奇怪。(.+)*


答案 1

让我们看看会发生什么:

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

评论中的一个好问题:

那为什么会回来呢?replace("input", "(input)*", "A$1B")"AinputBAB"

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

答案 2