c++:在macOS上具有负向前看和^匹配的正则表达式,但在Linux上不匹配



为什么相同的正则表达式在macOS(和Windows)上报告匹配,而在Linux上却没有?

下面是c++的示例代码:
#include <iostream>
#include <regex>
int main() {
std::regex rx("^(((?!(\/|^)\.).)*?)$");
std::string input = "foo.bar";
std::cout << std::regex_match(input, rx) << std::endl;
}

macOS和Windows上的结果:1

Linux上的结果(试用GCC 11):0

这个问题似乎源于负面展望?!(\/|^)。具体地说,删除|^解决了这个问题,因此它与^的负面前瞻性有关。

试图使用std::regex_match(input, rx, std::regex_constants::match_not_bol)没有运气。

有趣的是,当目标字符串不包含.时,结果还是一样的。

最后,同一正则表达式在JavaScript中运行时也可以在所有平台上匹配。

使用的编译器版本的一些详细信息:

  • macOS:Apple clang version 14.0.0 (clang-1400.0.29.202)
  • Linux:g++-11 (Ubuntu 11.1.0-1ubuntu1~20.04) 11.1.0
  • Windows:Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30133 for x86

当我想到跨平台的正则表达式实现时,我只想到两个库。

首先是Perl5语法的重新实现:https://github.com/PCRE2Project/pcre2

第二个是实现Python语法子集的小库:https://github.com/kokke/tiny-regex-c

我希望这对你有帮助。

不同的操作系统使用不同的正则表达式引擎。

请参阅https://en.wikipedia.org/wiki/Comparison_of_regular_expression_engines languages表中的POSIX C (C)

c++标准库提供了基于POSIX扩展正则表达式(ERE)语法的正则表达式引擎参考:- POSIX扩展正则表达式语法

^-字符用于匹配正则表达式中字符串的开头,但在ERE语法中,它在组内使用时也具有特殊含义。在ERE语法中,组中的^字符否定了它后面的字符类,所以在这种情况下,组中的^字符(/|^)否定了字符类。这将导致正则表达式引擎匹配任何不是.的字符,这就是为什么当目标字符串包含.时,行为是不同的。性格。

你需要去掉^字符:

std::regex rx("^(((?!(\/|^)).)*?)$");

最新更新