Проблема с boost :: find_format_all, boost :: regex_finder и пользовательским формататором регулярных выражений (bug boost 1.42) - PullRequest
2 голосов
/ 26 мая 2010

У меня есть код, который работает почти 4 года (начиная с версии 1.33), и сегодня я перешел с версии 1.36 на версию 1.42, и теперь у меня проблема.

Я звоню в пользовательский форматировщикв строке для форматирования частей строки, соответствующих REGEX.

Например, строка типа: "abc; def:" будет заменена на "abc \ 2Cdef \ 3B", если REGEX содержит "([;:]) "

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;
  }

}

Это работало нормально, но с бустом 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 Кажется, ошибка в (по крайней мере) повышении 1.42

1 Ответ

2 голосов
/ 26 мая 2010

Структура 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;
  }

}

РЕДАКТИРОВАТЬ: Посмотрите, как 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;      
    }
}
...