2

私は、ほぼ 4 年間 (boost 1.33 から) 動作しているコードを持っています。今日、boost 1.36 から boost 1.42 に変更したところ、問題が発生しました。

REGEX に一致する文字列の一部をフォーマットするために、文字列に対してカスタム フォーマッタを呼び出しています。

たとえば、次のような文字列: "abc;def:" は、REGEX に "([;:])" が含まれている場合、"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() があることがわかっています。

これは、文字列をフォーマットするためにファンクターにいることがあるが、一致しないことを意味します。

私は何か間違ったことをしていますか?それとも、一致するものがなく、何かをチェックする必要があるときにファンクターに入るのが普通ですか?

今のところ私の解決策は、{}catch(){} 例外を試すことです。すべて正常に動作しますが、どういうわけかあまり気分が良くありません。

編集1

実際には、解析する各文字列の最後に新しい空の一致があります。

EDIT2:ablaeulに触発された1つのソリューション

  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 のバグのようです

4

1 に答える 1

2

構造体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;      
    }
}
于 2010-05-26T16:07:50.133 に答える