Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::regex_替换n次发生并获取替换数_C++_Regex_C++11_Std - Fatal编程技术网

C++ std::regex_替换n次发生并获取替换数

C++ std::regex_替换n次发生并获取替换数,c++,regex,c++11,std,C++,Regex,C++11,Std,我正在使用std::regex\u replace修改字符串。我既需要限制替换,也需要完成替换的数量 我使用了以下代码: std::wregex rx(pattern); size_t n = 0; // one match size_t ns = 3; wstring result = src; wstring old; // old value bool replaced = false; do { old = result; result = std::regex_rep

我正在使用std::regex\u replace修改字符串。我既需要限制替换,也需要完成替换的数量

我使用了以下代码:

std::wregex rx(pattern);
size_t n = 0; // one match
size_t ns = 3;
wstring result = src;
wstring old; // old value
bool replaced = false;

do {
    old = result;
    result = std::regex_replace(result, rx, replace, std::regex_constants::format_first_only);
    replaced = result != old;
    if (replaced)
        n++;
} while (replaced && n < ns); 

它生成以下输出:ban---ana而不是ban-an-a。显然,这是因为std::regex_replace从一开始就分析字符串。一个解决方案可能是使用迭代器定义要分析的第一个字符,但在这种情况下,我需要获取迭代器,该迭代器指向那些被replcased的字符之后的字符,但如何获取它呢?

您可以设置计数器并使用回调。这将仅替换您设置的最大值。
(未经测试)

static int REPL_count=0;
静态int REPL_max=0;
静态字符串REPL_replace=“”;
字符串REPLcallback(const wsmatch m)
{
//如果低于最大计数,则返回格式化匹配
如果(复制计数<复制最大值)
{
++REPL_计数;
返回m.format(REPL_replace);
}
//超出计数,只返回匹配项而不设置格式
返回字符串(m[0]。第一个,m[0]。第二个);
}
int替换文本(
弦与弦,
弦与弦,
雷杰克斯正则表达式,
字符串和字符串替换,
整数(最大值)
{
REPL_计数=0;
REPL_max=max;
REPL_replace=strReplacement;
strOut=regex\u replace(strIn、regex、REPLcallback);
返回REPL_计数;
}

这比我想象的要复杂。我没有发现std::regex_replace()函数在这里非常有用

我决定使用直接的
std::wsregex_迭代器
解决方案,该解决方案基于以下实现描述中建议的算法:

这就是我想到的:

#include <regex>
#include <string>
#include <iterator>
#include <iostream>

int main()
{
    std::size_t ns = 3;
    std::wstring text = L"banana";
    std::wstring pattern = L"(an)";
    std::wstring replace = L"$1-";
    std::wstring result;

    std::wregex rx(pattern);

    auto iter = std::wsregex_iterator(text.begin(), text.end(), rx);
    auto stop = std::wsregex_iterator();
    auto last_iter = iter;

    auto out = std::back_inserter(result);

    for(std::size_t n = ns; n-- && iter != stop; ++iter)
    {
        out = std::copy(iter->prefix().first, iter->prefix().second, out);
        out = iter->format(out, replace);
        last_iter = iter;
    }

    out = std::copy(last_iter->suffix().first, last_iter->suffix().second, out);

    std::wcout << "  text: " << text << '\n';
    std::wcout << "result: " << result << '\n';
}

你很幸运,因为有两个重载正是你想要的,即处理迭代器而不是字符串,包括返回一个迭代器。我知道这个重载,但你能提供一个例子吗?基本上你要替换相同的东西3次。这就是你被禁止的原因。因为您每次从字符串的开头开始传递字符串。但是,还有另一种方法。OP声明他使用std::regex_replace()。您提供的代码不适用于std::regex_replace()。std::regex_replace()没有回调参数。您的建议可能需要regex_replace()的增强版本。
static int REPL_count = 0;
static int REPL_max = 0;
static string REPL_replace = "";


string REPLcallback( const wsmatch m )
{
    // Return formatted match if under the max count
    if ( REPL_count < REPL_max )
    {
        ++REPL_count;
        return m.format( REPL_replace );
    }
    // Exceeded count, just return match without formatting
    return string(m[0].first, m[0].second);
}

int ReplaceText(
         string& strIn,
         string& strOut,
         wregex  Regex,
         string& strReplacement,
         int     max )
{
    REPL_count = 0;
    REPL_max = max;
    REPL_replace = strReplacement;
    strOut = regex_replace( strIn, Regex, REPLcallback );
    return REPL_count;
}
#include <regex>
#include <string>
#include <iterator>
#include <iostream>

int main()
{
    std::size_t ns = 3;
    std::wstring text = L"banana";
    std::wstring pattern = L"(an)";
    std::wstring replace = L"$1-";
    std::wstring result;

    std::wregex rx(pattern);

    auto iter = std::wsregex_iterator(text.begin(), text.end(), rx);
    auto stop = std::wsregex_iterator();
    auto last_iter = iter;

    auto out = std::back_inserter(result);

    for(std::size_t n = ns; n-- && iter != stop; ++iter)
    {
        out = std::copy(iter->prefix().first, iter->prefix().second, out);
        out = iter->format(out, replace);
        last_iter = iter;
    }

    out = std::copy(last_iter->suffix().first, last_iter->suffix().second, out);

    std::wcout << "  text: " << text << '\n';
    std::wcout << "result: " << result << '\n';
}
  text: banana
result: ban-an-a