Есть ли вариант regex_replace, который поддерживает встроенный код?

Perl имеет e модификатор regex, который позволяет Perl-коду, а не просто строке, формулировать замену: http://perldoc.perl.org/perlretut.html#Search-and-replace Хотя этот пример не самый лучший, так как для этого есть переключатели. Для тех из вас, кто понимает Perl, вот пример, который имеет больше смысла:

$string = "StackOverflow user: Jonathan Mee";

$string =~ s/:\s*(.*)$/$1 == "Jonathan Mee" ? ": ".$1." is AWESOME!" : ": ".$1." is ???"/e;

print $string; #Will print "StackOverflow user: Jonathan Mee is AWESOME!"

Есть ли regex_replace вариант в C ++, что позволит мне сделать что-то подобное? Как в коде, встроенном для замены.

0

Решение

regex_replace имеет 6 разных перегрузок. fmt Аргумент используется одинаково для каждого из них:

Строка с заменой для каждого совпадения.
Это может включать спецификаторы формата и escape-последовательности, которые заменяются символами, которые они представляют.

Каждая из 6 перегрузок также имеет flags аргумент, который используется для контроля, «как fmt отформатирован. » fmt связанные варианты:

  • format_default: Форматирование по умолчанию
    Использует стандартные правила форматирования для замены совпадений (те, которые используются методом замены ECMAScript).
  • format_sed форматирование sed
    Для замены совпадений используются те же правила, что и для утилиты sed в POSIX.
  • format_no_copy Нет копии
    Разделы в целевой последовательности, которые не соответствуют регулярному выражению, не копируются при замене совпадений.
  • format_first_only Только первый
    Только первое вхождение регулярного выражения заменяется.

Обратите внимание, что ни один из fmt перегрузки, ни flags поддержка встроенного кода. Итак, ответ: Нет, варианта нет regex_replace который поддерживает встроенный код.


Однако, если вы готовы использовать алгоритм STD в сочетании с regex_iterator, Вы можете использовать лямбду для выполнения встроенного кода.

const string foo("StackOverflow user: Jonathan Mee");
vector<string> bar;

transform(regex_iterator<string::const_iterator>(foo.cbegin(), foo.cend(), regex(".*:\\s*(.*)")),
regex_iterator<string::const_iterator>(),
back_inserter(bar),
[](const smatch& i){auto result = i.str();

if (!result.empty()){
result += (i.str(1) == "Jonathan Mee" ? " is AWESOME!" : " is ???");
}
return result;});

Как вы можете видеть, лямбда может использоваться в transform принимая в течении regex_iterator«s smatch, Это очень расширяемо для многострочных строк, в примере string foo("StackOverflow user: Jonathan Mee\nStackOverflow user: user0"); результат будет:

Пользователь StackOverflow: Джонатан Ми — УДИВИТЕЛЬНЫЙ!
Пользователь StackOverflow: user0 is ???

Очевидно, что есть некоторые компромиссы, работающие только с smatch против regex_replace, куда str(1) попадает в str() не указано Здесь я пользуюсь тем фактом, что это прямо в конце foo а не где-то, что должно быть найдено в середине foo, Но следует отметить, что такая же сложность встречается и у Perl e-модификатор, так что я думаю, что это в значительной степени на одном уровне.

0

Другие решения


По вопросам рекламы [email protected]