带有Boost的regex_search和regex_replace [英] regex_search and regex_replace with Boost

查看:372
本文介绍了带有Boost的regex_search和regex_replace的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在一行中以 $对分隔的某些字符串之间循环,用特定值替换每个匹配项,以便获得替换了所有标记的输出行,但我被卡在第二个匹配项中因为我不知道如何连接新的替换值:

I'm trying to loop among some strings delimited by a '$' pair in a line, replacing each match with a specific value in order to get an output line with all markers replaced but I'm stuck at the second match as I don't know how to concatenate the new replacement value:

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已经保存了下一个匹配之前的一些字符。

The problem is in the outLine.append( t.str() ) as the concatenation is not done properly because after the first match, the outLine holds already some of the characters preceding the next match.

推荐答案

由于您仅请求替换字符串中的第一个值(通过使用 boost :: format_first_only 标志),因此原始字符串

Since you request only first value in a string to be replaced (by using boost::format_first_only flag) original string

"Mr $SURNAME$ from $LOCATION$"

将转换为

"Mr ACTUAL_VAL from $LOCATION$"

第一次迭代,然后

" from ACTUAL_VAL"

将被附加到该位置,因为您明确将开始设置为 what [0] .second。
,因此最终输出为

will be appended to it since you explicitly set begin to "what[0].second. so final output is

"Mr ACTUAL_VAL from $LOCATION$ from ACTUAL_VAL"

这不是您所需要的
这是工作示例具有副作用-它会修改fileLine:

which is not what you need. Here is working example that has side effect - it modifies 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,则应将开始和结束标记只包含一个模式的滑动窗口的开始和结束。

If you don't want to modify fileLine, then you should make "begin" and "end" to mark the beginning and end of sliding window that contains exactly one pattern.

这篇关于带有Boost的regex_search和regex_replace的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆