首页 > 解决方案 > boost::regex_constants::error_type 到字符串

问题描述

我有一个函数检查表达式是否与正则表达式匹配,并返回 boost::regex_constants::error_type,它会在出现异常时记录错误:

boost::regex_constants::error_type RegexMatch(const std::string& p_expression, const std::string& p_pattern)
{
    boost::regex_constants::error_type returnValue = boost::regex_constants::error_unknown;

    try
    {
        if (boost::regex_match(p_expression, boost::regex(p_pattern)))
        {
            returnValue = boost::regex_constants::error_ok;
        }
        else
        {
            returnValue = boost::regex_constants::error_no_match;
        }
    }
    catch(boost::regex_error& e)
    {
        returnValue = e.code();
        LOG_ERROR("Error checking if [%s] expression matches pattern [%s]: boost::regex_error [%s]",
                  p_expression.c_str(),
                  p_pattern.c_str(),
                  e.what());
    }

    return returnValue;
}

但是在客户端,调用者只获得boost::regex_constants::error_type结果,而根据上下文,客户端可能希望显示“人类可读”错误。

现在我的问题是知道是否有一个本机增强功能可以做到这一点?因为找不到,所以我做了自己的功能:

std::string BoostRegexErrorTypeToString(const boost::regex_constants::error_type p_boostRegexErrorType)
{
    return boost::regex_error(p_boostRegexErrorType).what();
}

请注意,我返回 astd::string而不是直接返回 a const char*(return by what()),因为在返回 a 时const char*,对于某些错误类型,例如error_ok,返回 "et*)" 而不是 "Success"。

最后,要测试此代码,您可以使用以下循环:

for (int intErrorType = boost::regex_constants::error_ok; // error_ok is the first
     intErrorType <= boost::regex_constants::error_unknown; // error_unknown is the last
     ++intErrorType)
{
    const boost::regex_constants::error_type errorType = (boost::regex_constants::error_type)intErrorType;
    LOG_DEBUG("Regex error [%d] text is [%s]",
              errorType,
              BoostRegexErrorTypeToString(errorType).c_str());
}

谢谢

标签: c++boostboost-regex

解决方案


首先,原因是

因为在返回 const char* 时,对于某些错误类型,例如 error_ok,返回 "et*)" 而不是 "Success"。

发生是因为您返回了一个过时的指针(what()指向实例内的成员数据runtime_error,并且在从您的函数返回后将被破坏!)。


用于获取错误字符串的函数 boost 是不公开的:

regex_error::regex_error(regex_constants::error_type err) 
   : std::runtime_error(::boost::BOOST_REGEX_DETAIL_NS::get_default_error_string(err))
   , m_error_code(err)
   , m_position(0) 
{
}

您可以看到它::boost::BOOST_REGEX_DETAIL_NS::get_default_error_string(err)位于详细名称空间中。

如果你愿意,你可以阅读源代码:

BOOST_REGEX_DECL const char* BOOST_REGEX_CALL get_default_error_string(regex_constants::error_type n)
{
   static const char* const s_default_error_messages[] = {
      "Success",                                                            /* REG_NOERROR 0 error_ok */
      "No match",                                                           /* REG_NOMATCH 1 error_no_match */
      "Invalid regular expression.",                                        /* REG_BADPAT 2 error_bad_pattern */
      "Invalid collation character.",                                       /* REG_ECOLLATE 3 error_collate */
      "Invalid character class name, collating name, or character range.",  /* REG_ECTYPE 4 error_ctype */
      "Invalid or unterminated escape sequence.",                           /* REG_EESCAPE 5 error_escape */
      "Invalid back reference: specified capturing group does not exist.",  /* REG_ESUBREG 6 error_backref */
      "Unmatched [ or [^ in character class declaration.",                  /* REG_EBRACK 7 error_brack */
      "Unmatched marking parenthesis ( or \\(.",                            /* REG_EPAREN 8 error_paren */
      "Unmatched quantified repeat operator { or \\{.",                     /* REG_EBRACE 9 error_brace */
      "Invalid content of repeat range.",                                   /* REG_BADBR 10 error_badbrace */
      "Invalid range end in character class",                               /* REG_ERANGE 11 error_range */
      "Out of memory.",                                                     /* REG_ESPACE 12 error_space NOT USED */
      "Invalid preceding regular expression prior to repetition operator.", /* REG_BADRPT 13 error_badrepeat */
      "Premature end of regular expression",                                /* REG_EEND 14 error_end NOT USED */
      "Regular expression is too large.",                                   /* REG_ESIZE 15 error_size NOT USED */
      "Unmatched ) or \\)",                                                 /* REG_ERPAREN 16 error_right_paren NOT USED */
      "Empty regular expression.",                                          /* REG_EMPTY 17 error_empty */
      "The complexity of matching the regular expression exceeded predefined bounds.  "
      "Try refactoring the regular expression to make each choice made by the state machine unambiguous.  "
      "This exception is thrown to prevent \"eternal\" matches that take an "
      "indefinite period time to locate.",                                  /* REG_ECOMPLEXITY 18 error_complexity */
      "Ran out of stack space trying to match the regular expression.",     /* REG_ESTACK 19 error_stack */
      "Invalid or unterminated Perl (?...) sequence.",                      /* REG_E_PERL 20 error_perl */
      "Unknown error.",                                                     /* REG_E_UNKNOWN 21 error_unknown */
   };

   return (n > ::boost::regex_constants::error_unknown) ? s_default_error_messages[ ::boost::regex_constants::error_unknown] : s_default_error_messages[n];

推荐阅读