boost::find_format_all、boost::regex_finder 和自定义正则表达式格式化程序存在问题(bug boost 1.42)

发布于 2024-09-03 01:24:08 字数 1363 浏览 7 评论 0原文

我有一个代码已经工作了近 4 年(从 boost 1.33 开始),今天我从 boost 1.36 升级到 boost 1.42,现在我遇到了问题。

我在字符串上调用自定义格式化程序来格式化与 REGEX 匹配的字符串部分。

例如,如果 REGEX 包含“([;:])”,则类似“abc;def:”的字符串将更改为“abc\2Cdef\3B”

boost::find_format_all( mystring, boost::regex_finder( REGEX ), custom_formatter() );

自定义格式化程序如下所示:

struct custom_formatter()
{

  template< typename T >
  std::string operator()( const T & s ) const
  {
      std::string matchStr = s.match_results().str(1);

      // perform substitutions

      return matchStr;
  }

}

这工作正常,但使用 boost 1.42我知道有“未初始化” s.match_results() ,它会产生 boost::exception_detail::clone_implINS0_::error_info_injectorISt11logic_errorEEEE - 尝试访问未初始化的 boost::match_results<>班级。

这意味着有时我在函子中格式化字符串但没有匹配。

我做错了什么吗?或者当没有匹配项时输入函子是否正常,我应该检查某些内容?

目前我的解决方案是尝试{}catch(){} 异常,一切正常,但不知何故感觉不太好。

EDIT1

实际上,我在每个字符串的末尾都有一个新的空匹配要解析。

EDIT2:一个受 ablaeul 启发的解决方案

  template< typename T >
  std::string operator()( const T & s ) const
  {

      if( s.begin() == s.end() ) return std::string();

      std::string matchStr = s.match_results().str(1);

      // perform substitutions

      return matchStr;
  }

EDIT3 似乎是(至少)boost 1.42 中的一个错误

I have a code that has been working for almost 4 years (since boost 1.33) and today I went from boost 1.36 to boost 1.42 and now I have a problem.

I'm calling a custom formatter on a string to format parts of the string that match a REGEX.

For instance, a string like: "abc;def:" will be changed to "abc\2Cdef\3B" if the REGEX contains "([;:])"

boost::find_format_all( mystring, boost::regex_finder( REGEX ), custom_formatter() );

The custom formatter looks like this:

struct custom_formatter()
{

  template< typename T >
  std::string operator()( const T & s ) const
  {
      std::string matchStr = s.match_results().str(1);

      // perform substitutions

      return matchStr;
  }

}

This worked fine but with boost 1.42 I know have "non initialized" s.match_results() which yield to boost::exception_detail::clone_implINS0_::error_info_injectorISt11logic_errorEEEE
- Attempt to access an uninitialzed boost::match_results<> class.

This means that sometimes I am in the functor to format a string but there is no match.

Am I doing something wrong? Or is it normal to enter the functor when there is no match and I should check against something?

for now my solution is to try{}catch(){} the exception and everything works fine, but somehow that doesn't feel very good.

EDIT1

Actually I have a new empty match at the end of each string to parse.

EDIT2 : one solution inspired by ablaeul

  template< typename T >
  std::string operator()( const T & s ) const
  {

      if( s.begin() == s.end() ) return std::string();

      std::string matchStr = s.match_results().str(1);

      // perform substitutions

      return matchStr;
  }

EDIT3 Seems to be a bug in (at least) boost 1.42

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

段念尘 2024-09-10 01:24:08

结构体 find_regexF 似乎是罪魁祸首。正如您所看到的,它返回一个空结果,并带有未初始化的 match_results()。浏览 SO 找到了以下解决方案:

struct custom_formatter()
{

  template< typename T >
  std::string operator()( const T & s ) const
  {
      std::string matchStr;
      for (typename T::const_iterator i = Match.begin();
             i != Match.end();
             i++) {
          // perform substitutions via *i
      }
      return matchStr;
  }

}

编辑:看看如何< a href="http://www.boost.org/doc/libs/1_36_0/boost/algorithm/string/detail/formatter_regex.hpp" rel="nofollow noreferrer">Boost 使用格式化程序 这里是另一个解决方案:

template<typename InputIteratorT>
std::string operator()( 
    const regex_search_result<InputIteratorT>& Replace ) const
{
    if ( Replace.empty() )
    {
        return std::string();
    }
    else
    {
        std::string matchStr = s.match_results().str(1);
        // perform substitutions
        return matchStr;      
    }
}

The struct find_regexF seems to be the culprit. As you can see, it returns an empty result with a uninitialized match_results(). Looking through SO found me the following solution:

struct custom_formatter()
{

  template< typename T >
  std::string operator()( const T & s ) const
  {
      std::string matchStr;
      for (typename T::const_iterator i = Match.begin();
             i != Match.end();
             i++) {
          // perform substitutions via *i
      }
      return matchStr;
  }

}

EDIT: Looking at how Boost uses the formatter here is another solution:

template<typename InputIteratorT>
std::string operator()( 
    const regex_search_result<InputIteratorT>& Replace ) const
{
    if ( Replace.empty() )
    {
        return std::string();
    }
    else
    {
        std::string matchStr = s.match_results().str(1);
        // perform substitutions
        return matchStr;      
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文