如何处理或避免来自C++ 11 <regex>匹配函数的异常(§28.11)?

jot*_*tik 10 c++ regex exception language-lawyer c++11

从C++ 11个的起始<regex>报头定义的功能std::regex_match,std::regex_search并且std::regex_replace§28.11.我想这些函数不存在是有正当理由的noexcept,但我找不到任何关于这些函数可能抛出的原因或原因.

  1. 这些函数可以抛出哪些类型的异常?
  2. 什么运行时条件会导致抛出这些异常?
    • 标准是否确保对于某些参数集,这些函数永远不会抛出,例如它是否确保regex_match(anyString, regex("."))从不抛出?

PS:由于其中一些异常可能继承std::runtime_error,他们可能会std::bad_alloc在构建过程中抛出.

Bar*_*rry 5

regex_error是唯一被提及的例外,因为它是从任何类或算法中抛出的<regex>.有两种基本类型的错误:格式错误的正则表达式和未能处理匹配.

如果传入的参数(或序列)是"不是有效的正则表达式",则构造函数basic_regex可以抛出regex_error(根据[re.regex.construct] \ 3,\ 7,\ 14\ 17).如果您尝试将a指定basic_regex给无效的正则表达式([re.regex.assign]/15),情况也是如此.

除此之外,算法也可以抛出regex_error([re.except]/1):

本条款中描述的函数通过抛出类型异常来报告错误regex_error.如果e抛出这样的例外,e.code()则应返回regex_constants::error_complexityregex_constants::error_stack.

这两个错误代码的意思是([re.err]):

error_complexity:尝试匹配正则表达式的复杂性超出了预设水平.
error_stack:没有足够的内存来确定正则表达式是否可以匹配指定的字符序列.


mce*_*ceo 3

C++11 \xc2\xa728.6状态

\n\n
\n

该类regex_error定义了作为异常抛出的对象类型,\n 以报告来自正则表达式库的错误。

\n
\n\n

这意味着<regex>库本身不应该抛出任何其他内容。您是正确的,构造一个regex_error继承自的对象可能会在构造过程中由于内存不足而runtime_error抛出异常,因此您还必须在错误处理代码中检查这一点。bad_alloc不幸的是,这使得无法确定哪个regex_error构造实际上抛出了异常bad_alloc

\n\n

对于 \xc2\xa728.11 中的正则表达式算法,在\xc2\xa728.11.1中指出

\n\n
\n

本节中描述的算法可能会抛出 类型的异常regex_errore如果抛出此类异常,e.code()则应返回regex_constants::error_complexityregex_-constants::error_stack

\n
\n\n

这意味着,如果 \xc2\xa728.11 中的函数抛出 a regex_error,它应保存这些代码之一,而不保存其他代码。但是,还要注意,您传递给<regex>库的内容(例如分配器等)也可能会抛出异常,例如,match_results如果将结果添加到给定match_results容器,则分配器可能会触发。另请注意, \xc2\xa728.11 具有“好像”构造的简写函数match_results,例如

\n\n
template <class BidirectionalIterator, class charT, class traits>\nbool regex_match(BidirectionalIterator first, BidirectionalIterator last,\n                 const basic_regex<charT, traits> & e,\n                 regex_constants::match_flag_type flags =\n                 regex_constants::match_default);\n\ntemplate <class BidirectionalIterator, class charT, class traits>\nbool regex_search(BidirectionalIterator first, BidirectionalIterator last,\n                  const basic_regex<charT, traits> & e,\n                  regex_constants::match_flag_type flags =\n                  regex_constants::match_default); \n
Run Code Online (Sandbox Code Playgroud)\n\n

可能还有其他。由于此类可能在内部构建和使用match_results标准allocator,因此它们可能会抛出任何std::allocator异常。regex_match(anyString, regex("."))因此,由于默认分配器的构造和使用,您的简单示例也可能会抛出异常。

\n\n

另一个需要注意的警告是,对于某些<regex>函数和类,目前无法确定 abad_alloc是由某些分配器抛出还是在构造过程中抛出regex_error

\n\n

一般来说,如果您需要具有更好的异常规范的东西,请避免使用<regex>. 如果您需要简单的模式匹配,那么最好滚动自己的安全匹配/搜索/替换函数,因为即使使用空正则,也不可能以可移植或向前兼容的方式约束正则表达式以避免这些异常表达式""可能会给你一个例外。

\n\n

PS:请注意,C++11 标准在某些方面写得相当糟糕,缺乏完整的交叉引用。例如,在条款下没有明确通知match_results抛出任何内容的方法,而\xc2\xa728.10.1.1声明(强调我的):

\n\n
\n

在所有match_results构造函数中,参数的副本Allocator应用于执行的任何内存分配构造函数或成员函数在对象生命周期内

\n
\n\n

因此,像律师一样浏览标准时要小心!;-)

\n