Получите итераторы из std :: regex_search и используйте их в string :: replace - PullRequest
0 голосов
/ 26 мая 2020

У меня нелепые трудности с сопоставлением регулярного выражения и заменой совпадения другой строкой. Я хочу добиться этого с помощью итераторов, как описано ниже. Часть, которая не работает, - это получение итераторов, которые разграничивают совпадение в исходной строке, и я мог бы затем перейти к string :: replace. Я попытался использовать объект std :: match_results, чтобы получить пару итераторов, но замена m на mr в вызове regex_search не удалась.

У меня смутное ощущение, что я либо использую неправильное совпадение класс или неправильный тип итератора, но почему-то не могу выбраться из джунглей шаблонов.

std::string txt{ "aaa bbb" };
std::smatch m;
std::regex rx(R"(aaa)");
std::match_results<std::string::iterator> mr;

if (std::regex_search(cbegin(txt), cend(txt), m, rx)) {
    std::cerr << m[0] << std::endl;

    // what I need here are iterators that I can pass
    // to string::replace

    // txt.replace(i1 ,i2, std::string("ccc"));
}

Ответы [ 3 ]

1 голос
/ 26 мая 2020

Попробуйте этот сегмент

std::string::const_iterator start = txt.begin();
std::string::const_iterator end   = txt.end();

if ( std::regex_search( start, end, m, rx ) ) 

Типичное использование в while l oop

while ( std::regex_search( start, end, m, rx ) )
{
    // do stuff with match
    start = m[0].second;
}
0 голосов
/ 27 мая 2020

Благодаря @Edward я понял, что m [0] содержит пару итераторов, которые определяют соответствующую подстроку. Я пробовал первый и второй, но на m вместо m [0], что, конечно, не удалось.

С этой заменой было легко:

std::string txt{ "aaa bbb" };
std::smatch m;
std::regex rx(R"(aaa)");

if (std::regex_search(cbegin(txt), cend(txt), m, rx)) {
    txt.replace(m[0].first, m[0].second, std::string("ccc"));
}
0 голосов
/ 27 мая 2020

Почему вы хотите заменить итераторы? Возможно, вы это знаете, но есть метод std::regex_replace, который может это сделать.

std::string stringText{ "aaa bbb" };
std::regex regexMatch("aaa");
std::string stringResult;

std::regex_replace(std::back_inserter(stringResult), std::cbegin(stringText), std::cend(stringText), regexMatch, "ccc");

Еще один аналогичный пример из учебника по регулярным выражениям с использованием regex_replace (прокрутите немного вниз)

Можно использовать итераторы, но тогда вам нужно построить новую строку из текущей. если хочешь, я могу сделать образец.

...