0

行内の「$」ペアで区切られたいくつかの文字列間でループしようとしています。すべてのマーカーが置き換えられた出力行を取得するために、各一致を特定の値に置き換えますが、2番目の一致でスタックしています'新しい置換値を連結する方法がわからない:

const boost::regex expression( "\\$[\\w]+\\$" );
string fileLine( "Mr $SURNAME$ from $LOCATION$" );
string outLine;

string::const_iterator begin = fileLine.begin();
string::const_iterator end = fileLine.end();

boost::match_results<string::const_iterator> what;
boost::match_flag_type flags = boost::match_default;

while ( regex_search( begin, end, what, expression, flags ) ) {
  actualValue = valuesMap[what[0]];

  ostringstream t( ios::out | ios::binary );
  ostream_iterator<char, char> oi( t );

  boost::regex_replace( oi, begin, end, expression, actualValue, 
                        boost::match_default | boost::format_first_only );
  outLine.append( t.str() );
  begin = what[0].second;
}

問題は outLine.append( t.str() ) にあります。これは、最初の一致の後、outLine が次の一致の前の文字の一部を既に保持しているため、連結が適切に行われないためです。

4

2 に答える 2

0

文字列の最初の値のみを置き換えるように要求するため ( boost::format_first_onlyフラグを使用して) 元の文字列

"Mr $SURNAME$ from $LOCATION$"

に変換されます

"Mr ACTUAL_VAL from $LOCATION$"

最初の繰り返しで

" from ACTUAL_VAL"

begin を「what[0].second」に明示的に設定したため、それに追加されます。したがって、最終出力は

"Mr ACTUAL_VAL from $LOCATION$ from ACTUAL_VAL"

これは必要なものではありません。副作用のある実際の例を次に示します-fileLineを変更します:

   const boost::regex expression( "\\$[\\w]+\\$" );
    string fileLine( "Mr $SURNAME$ from $LOCATION$" );
    string outLine;

    string::const_iterator begin = fileLine.begin();
    string::const_iterator end = fileLine.end();

    boost::match_results<string::const_iterator> what;
    boost::match_flag_type flags = boost::match_default;

    while ( regex_search( begin, end, what, expression, flags ) ) 
    {
        const char* actualValue = valuesMap[what[0]];

        ostringstream t( ios::out | ios::binary );
        ostream_iterator<char, char> oi( t );

        boost::regex_replace( oi, begin, end, expression, 
`enter code here`actualValue, boost::match_default | boost::format_first_only );

        fileLine.assign(t.str());
        begin = fileLine.begin();
        end = fileLine.end();        
    }

    std::cout << fileLine << std::endl;

fileLine を変更したくない場合は、"begin" と "end" を作成して、1 つのパターンを含むスライディング ウィンドウの開始と終了をマークする必要があります。

于 2011-03-15T21:27:28.643 に答える
0

あなたの意図について 100% 確信があるわけではありませんが、あなたの目標は、一致した各部分文字列fileLineを の対応する値に置き換えることだと思いますvaluesMap
もしそうなら、次のコードはあなたの目的を満たしているかもしれません:

  ...same as your code...

  while ( regex_search( begin, end, what, expression, flags ) ) {
    outLine.insert( outLine.end(), begin, what[0].first );
    outLine += valuesMap[what[0]];
    begin = what[0].second;
  }

  outLine.insert( outLine.end(), begin, end );

お役に立てれば

于 2011-03-15T21:39:17.327 に答える