代码之家  ›  专栏  ›  技术社区  ›  kayleeFrye_onDeck

<regex>std::regex等价于Qt的QRegularExpression::isValid(),没有触发异常

  •  2
  • kayleeFrye_onDeck  · 技术社区  · 7 年前

    isValid()

    在std中 <regex> ,我看不出有什么办法。所以现在,我有 try/catch 块,使正则表达式具有用户提供的正则表达式,然后尝试将其与1字符字符串匹配,以快速触发 std::regex_error std::regex .我基本上是在使用该工具的自动输入时,试图避免捕捉和处理异常的性能问题。

    try
    {
        const std::regex regex_exception_trigger(regex_string);
        std::smatch stability_match;
        const std::string test_string = "0";
        if (std::regex_search(test_string.begin(), test_string.end(), stability_match, regex_exception_trigger)) {}
    }
    catch (std::regex_error &re) { std::cerr << re.what() << std::endl; print_help(); return exit_enum::BAD_REGEX;  }
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   user557597 user557597    7 年前

    如果您想捕获所有错误,请在try{}catch{}catch{}catch{{}序列中执行所有操作。

    我将把结构和使用分开。

    伪代码

    std::regex Rx;
    bool bIsConstructError = false;
    
    ////////////////////////////////////////
    bool SetRx( std::string& strRx )
    {
       bIsConstructError = false;
       try 
       {
          Rx.assign( "", 0);
          Rx.assign( strRx, 0 );
       }
       catch ( std::regex_error & e )
       {
          bIsConstructError = true;
          return false;
       }
       catch ( std::out_of_range & e )
       {
          bIsConstructError = true;
          return false;
       }
       catch ( std::runtime_error & e )
       {
          bIsConstructError = true;
          return false;
       }
       return true;
    }
    
    ////////////////////////////////////////
    bool  findText( std::string& strTarget )
    {
       if ( bIsConstructError )
          return false;
    
       bool bRet = true;
    
       std::smatch _M;
       std::string::const_iterator start = strTarget.begin();
       std::string::const_iterator end = strTarget.end();
    
       try
       {
          if ( regex_search( start, end, _M, Rx, 0 ) )
          {
              // do something
          }
       }
       catch ( std::out_of_range & e )
       {
          bRet = false;
       }
       catch ( std::runtime_error & e )
       {
          bRet = false;
       }
       return bRet;
    }
    
        2
  •  1
  •   SJL    7 年前

    这通常是好的,因为它清楚地表明了哪里出了错:如果我试图用一个构造错误的正则表达式解析一个字符串,我得到了一个异常,那么自然的想法是字符串有问题,而不是正则表达式。

    您的用例并不适合这种模式,因为C++标准库假设构造不良的正则表达式是异常的(因此是异常)。

    当不抛出异常时,异常是廉价的(即,对于 try-catch 如果您不需要捕获任何内容,请阻止),但实际上捕获异常可能会非常昂贵。如果您希望收到大量构造不正确的正则表达式,并且您认为捕捉异常会显著影响性能(尽管捕捉异常的成本很高,但您可能仍然可以,因此您应该做一些测试),那么在构造正则表达式之前,您需要考虑另一种工具来验证正则表达式。

    Boost还提供了标准库版本所基于的正则表达式库。语法将非常相似。Boost的版本有一个 no_except 可以传递给正则表达式构造函数并将抑制无效字符串的任何异常的标志。我在上面给出的原因大概是为什么这个标志没有包含在标准库版本中。如果需要这种行为,可以考虑改用Boost版本。