为什么相同的正则表达式在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("^(((?!(\/|^)).)*?)$");