Regex_replace两次匹配字符串的结尾

regex_replace matches end of string twice

本文关键字:字符串 结尾 两次 replace Regex      更新时间:2023-10-16

考虑以下程序:

#include <iostream>
#include <regex>
int main(int argc, char* argv[]) {
  if (argc==4)
    std::cout << std::regex_replace(
        argv[1], std::regex(argv[2]), argv[3]
      ) << std::endl;
}

运行

./a.out a_a_a '[^_]+$' b

给出了预期的结果a_a_b。但是运行

./a.out a_a_a '[^_]*$' b

打印a_a_bb

boost::regex_replace具有相同的行为。

我不明白为什么最后一个a之后的空字符串再次匹配,当我已经消耗$时。

锚点不会被消耗(因为它们是0宽)。

您可以尝试使模式abc$$$与字符串abc匹配,并且它仍然会像模式^^^abc一样匹配。因此,您的功能中的$不会被消耗,并且允许a$(empty)$匹配。

这是*量词和+量词之间的简单差异。*匹配结尾字母a以及末端的零宽度。

您可以在这里看到它:

[^_]*$

不仅与最后一个a匹配,而且与此后的零宽度匹配,因此结果将是a_a_bb


确定它如何以这种方式工作:

[^_]*

,如果您喂养程序a_a_a,输出将是:

bb_bb_bb

[^_]*


请注意,模式[^_]匹配所有三个a s,但是一旦您在此模式之后放置星号*,它就会产生模式:匹配单个A或NOTHER(=零宽)>因此,针对主题a_a_a匹配的模式[^_]* 6 点:a以及a_之间等等。

a_a_a
^^^^^^

我认为是因为

+ means 1 or many (at least one occurrence for the match to succeed)
* means 0 or many (the match succeeds regardless of the presence of the search string)

因此,[^_]+$仅匹配[^_]*$匹配A和空字符,因此它是双b