我有这个代码:
class Clazz {
private:
constexpr char _csVersionPattern[] = "^[^\\(\\[\\)\\],]+$";
//constexpr char _csVersionPattern[] = "(^([\\(\\[])[!-'\\*+\\.-Z\\\\^-z\\|~-]*,[!-'\\*+\\.-Z\\\\^-z\\|~-]*([\\)\\]])$)|(^[^\\(\\[\\)\\],]+$)";
constexpr char _csIdPattern[] = "^[!-~]+$";
public:
void func(std::string const& aId, std::string const& aVersion) {
std::regex idRegex{ _csIdPattern, std::regex::extended };
std::regex versionRegex{ _csVersionPattern, std::regex::extended };
auto validId = std::regex_match(aId, idRegex);
auto validVersion = std::regex_match(aVersion, versionRegex);
_valid = (validId && validVersion);
}
};
当我将其称为 object.func("id", "version");
validId 将为 true,validVersion 为 false。如果我在评论中采用更复杂的模式,它也会失败。这种情况在 Visual Studio 2019 中发生,在最近的 g++ 和 clang++ 中也发生。但是,当我尝试here时相同版本模式:
^[^\(\[\)\],]+$
它与字符串“version”匹配。复杂的变体也有效。这些模式在 std::regex 构造函数中编译(也不异常(exception))。我做错了什么?
提前致谢。
编辑: Here它在Godbolt 上。原来是C++14,这里是C++17,都失败了。
最佳答案
您编写的正则表达式与 ECMAScript 兼容,但您选择了 std::regex::extended
风格,即 POSIX ERE .
在 POSIX ERE 模式中,不能使用正则表达式转义序列。例如,您不能将 \]
放在括号表达式内并期望它与文字 ]
匹配。事实上,它会提前关闭括号表达式。 ^[^\(\[\)\],]+$
正则表达式必须写为 ^[^][(),]+$
作为 ]
位于括号表达式的开头,被视为文字 ]
字符(这称为智能放置,-
顺便说一下,> 必须用在括号表达式的末尾)。
这里最简单的修复方法是删除 std::regex::extended
选项并使用默认的 ECMAScript 选项:
std::regex idRegex{ _csIdPattern };
std::regex versionRegex{ _csVersionPattern };
关于C++ 正则表达式失败,而在线检查器正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66212718/