从std::regex中提取原始regex模式
extracting original regex pattern from std::regex
我有一个函数,它试图将给定的字符串与给定的正则表达式模式进行匹配。如果不匹配,它应该创建一个字符串来指示这种情况,并包括失败的正则表达式模式和字符串的内容。类似的东西:
bool validate_content(const std::string & str, const std::regex & pattern, std::vector<std::string> & errors)
{
if ( false == std::regex_match(str, pattern) )
{
std::stringstream error_str;
// error_str << "Pattern match failure: " << pattern << ", content: " << str;
errors.push_back(error_str.str());
return false;
}
return true;
}
然而,正如您所看到的,注释行提出了一个挑战:是否可以恢复regex对象的原始模式?
很明显,有一种变通方法,即提供原始模式字符串(而不是regex对象或在regex对象旁边),然后使用它。但是,我当然不需要在每次调用此函数时重新创建regex对象(每次调用函数时重新生成模式的成本很高),也不需要将regex模式与regex对象一起传递(很容易出现拼写错误和错误,除非我提供一个包装器来帮我这样做,这并不方便)。
我在Ubuntu 14.04上使用GCC 4.9.2。
boost::basic_regex
对象有一个str()
函数,该函数返回用于构造正则表达式的字符串的(副本)。(它们还提供了begin()
和end()
接口,它们将迭代器返回到字符序列,以及用于内省捕获子表达式的机制。)
这些接口在最初的TR1 regex标准化提案中,但在2003年采用n1499:在basic_regex中简化接口后被删除,我引用了以下内容:
basic_regex不应保留其Initializer的副本
basic_regex
模板有一个成员函数str
,它返回一个字符串对象,该对象包含用于初始化basic_regex
对象的文本……虽然查看初始化器字符串偶尔会很有用,但我们应该应用这样一条规则,即如果不使用它,就不必为此付费。就像fstream
对象不附带打开时使用的文件名一样,basic_regex
对象不应携带其初始值设定项文本。如果有人需要跟踪该文本,他们可以编写一个包含该文本和basic_regex
对象的类。
根据标准N4431§28.8/2类模板basic_regx[re.regex](Emphasis mine):
basic_regex
类型特殊化的对象负责转换charT
对象的序列内部表示。没有指定此表示采用何种形式,也没有指定如何访问对正则表达式进行运算的算法[注意:实现通常会将一些函数模板声明为basic_regex
的朋友,以实现这一点--结束注意]
因此,basic_regex
对象不需要在内部保持原始字符序列。
因此,必须在创建regex
时存储字符序列。例如:
struct RegexPattern {
std::string pattern;
std::regex reg;
};
...
bool validate_content(const std::string & str, const RegexPattern & pattern, std::vector<std::string> & errors) {
if(false == std::regex_match(str, pattern.reg)) {
std::stringstream error_str;
error_str << "Pattern match failure: " << pattern.pattern << ", content: " << str;
errors.push_back(error_str.str());
return false;
}
return true;
}
另一个由@Praetorian提出的更优雅的解决方案,但效率稍低(我还没有对这两个版本进行基准测试,因此我不确定)。将保留模式字符串并将其作为输入参数传递给函数validate_content
,然后在内部创建regex
对象,如下所示:
bool validate_content(const std::string & str, const string & pattern, std::vector<std::string> & errors) {
std::regex reg(pattern);
if(false == std::regex_match(str, reg)) {
std::stringstream error_str;
error_str << "Pattern match failure: " << pattern << ", content: " << str;
errors.push_back(error_str.str());
return false;
}
return true;
}
- 将浮动的heightmap数组导出为16位原始值
- 此模式的C++RegEx
- 给定一个向量,如何找到该向量的所有子集和的原始索引
- 有没有办法从非C/C++文件中读取C++原始字符串文字的内容
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- 如何将原始字节附加到 std::vector?
- 从堆栈分配的原始指针构造智能指针
- 如何重写全局方法名称以在调用原始方法之前将我的代码推到前面
- 将unique_ptr分配给原始指针
- 是否可以从 OpenGL 缓冲区获取原始大小的像素?
- 使用 OpenSSL 从内存中读取原始 SSL/TLS 证书
- 如何将唯一指针的 std::vector 转换为原始指针的 std::span?
- 从原始字节解码协议缓冲区(以 C++为单位)
- C ++如何在原始抽象类中创建一个函数,该函数接受派生类的输入
- C++ std::regex 使用前瞻失败
- C++:尝试使用等效的 STL 算法消除原始循环
- 如何在连接器 C++ 中将原始字节转换为字符串
- 通过引用传递类不会更改原始类
- std::regex:匹配由数字和空格组成的字符串,并提取数字.如何?
- 从std::regex中提取原始regex模式