std::regex-前瞻断言并不总是有效
我正在编写一个模块,该模块将一些字符串替换为文本以提供给脚本语言。该语言的语法模糊不清,因此表达式以括号和空格分隔的符号为界,其中大多数以 '$' 开头。像这样的正则表达式似乎应该在适当的符号边界处给出匹配:
auto re_match_abc = std::regex{ "(?=.*[[:space:]()])$abc(?=[()[:space:]].*)" };
但是在我的环境中(Visual C++ 2017, 15.9.19,targeting C++-17)它可以匹配前面没有合适边界的字符串:
std::cout << " $abc -> " << std::regex_replace(" $abc ", re_match_abc, "***") << std::endl;
std::cout << " ($abc) -> " << std::regex_replace("($abc)", re_match_abc, "***") << std::endl;
std::cout << "xyz$abc -> " << std::regex_replace("xyz$abc ", re_match_abc, "***") << std::endl;
std::cout << " $abcdef -> " << std::regex_replace(" $abcdef", re_match_abc, "***") << std::endl;
// Result from VC++ 2017:
//
// $abc -> ***
// ($abc) -> (***)
// xyz$abc -> xyz*** <= What's going wrong here?
// $abcdef -> $abcdef
为什么那个正则表达式忽略了在匹配文本之前至少有一个空格或括号的正向预测要求?
[我意识到还有其他方法可以完成这项工作,并且要真正稳健地完成,也许我应该使用某些东西将字符串转换为令牌流,但是对于我的直接工作(并且因为创作字符串的人被处理坐在我旁边,所以我们可以协调)我认为现在可以使用正则表达式替换。]