C++ std::regex反向引用报错,求ABA型字符串匹配解决方案
解决C++ std::regex的反向引用错误问题
嘿,我一眼就看到问题所在了,咱们拆解来看:
首先,你在regexr上用的是正向否定前瞻 (?!\1),但在C代码里误写成了反向否定后顾 (?<!\1)——这俩差别可大了!反向后顾是用来检查当前位置前面的内容,而且更关键的是:在libc的std::regex实现里,反向后顾断言里根本不能用捕获组的反向引用(比如\1),这直接触发了你看到的regex_error。
其次,虽然你在字符串里对\做了转义(写成\\1)是对的,但用C++的原始字符串字面量会更省心,不用反复写双重转义,可读性也强很多。
给你修正后的代码,还加了测试用例方便验证:
#include <regex> #include <iostream> #include <string> int main() { try { // 用原始字符串字面量,避免双重转义的麻烦 std::regex regex_test2(R"(([a-z]+)_(?!\1)([a-z]+)_\1)"); // 测试示例 const std::string valid_case = "allen_bob_allen"; const std::string invalid_case = "allen_allen_allen"; std::cout << std::boolalpha; std::cout << valid_case << " 是否有效:" << std::regex_match(valid_case, regex_test2) << "\n"; std::cout << invalid_case << " 是否有效:" << std::regex_match(invalid_case, regex_test2) << "\n"; } catch (const std::regex_error& e) { std::cerr << "正则表达式错误:" << e.what() << "\n"; } return 0; }
额外提两个小细节:
- 正向否定前瞻
(?!\1)在这里的作用是确保第二个部分和第一个捕获组的内容不一样,完全符合你A≠B的需求。 - 如果你用的是macOS上的clang(默认链接libc++),它对ECMAScript风格的正则支持很到位,但反向后顾有个限制:它要求匹配的内容是固定长度的,而反向引用
\1的长度是可变的,所以哪怕你没写错符号,在反向后顾里用\1也会报错。
这样修改后,你的正则就能正常工作啦!
内容的提问来源于stack exchange,提问作者Juude
相关产品推荐
相关产品推荐

