[英]std::regex_replace replace n occurences and get number of substitutions
I'm using std::regex_replace to modify the string. 我正在使用std :: regex_replace修改字符串。 I need both to restrict substitutions made and to get number of them done. 我既需要限制替换,也要完成替换。
I used following code: 我使用以下代码:
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);
It works fine, I can both restrict substitutuins amount and get their number. 它工作正常,我既可以限制替换基团的数量,也可以获取它们的数量。 But this code analyzes the string from its start, as a result, if I have following values: 但是,如果我具有以下值,那么此代码将从一开始就分析字符串:
"banana" for src, "(an)" for pattern and "$1-" for replace
it produces following output: ban---ana instead of ban-an-a. 它产生以下输出:ban --- ana而不是ban-an-a。 Obviously, this is because std::regex_replace analyzes string from start. 显然,这是因为std :: regex_replace从一开始就分析了字符串。 A solution might be to use iterators to define first character to analyze, but in this case I need to get iterator that points to characters after those that were replcased, but how can I get it? 一种解决方案可能是使用迭代器来定义要分析的第一个字符,但是在这种情况下,我需要获取指向被替换字符之后的字符的迭代器,但是我如何获得它呢?
This turned out to be trickier than I thought. 事实证明这比我想象的要难。 I didn't find any of the std::regex_replace()
functions very helpful here. 我发现这里没有任何std::regex_replace()
函数非常有用。
I decided to go with a straight std::wsregex_iterator
solution based on the algorithm suggested in the implementation descriptions here: 我决定根据此处实现说明中建议的算法,使用简单的std::wsregex_iterator
解决方案:
http://en.cppreference.com/w/cpp/regex/regex_replace http://en.cppreference.com/w/cpp/regex/regex_replace
This is what I came up with: 这是我想出的:
#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';
}
Output: 输出:
text: banana
result: ban-an-a
You can set up a counter and use a callback. 您可以设置一个计数器并使用回调。 This will only replace the maximum you set. 这只会替换您设置的最大值。
(Untested) (未测试)
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.