Итак, вы используете так называемый PCRE аромат. Хорошо, если не сказать точно, какую библиотеку вы используете. Давайте рассмотрим несколько вариантов здесь, так как несколько разных библиотек утверждают, что они совместимы с Perl.
подталкивания
Это самое простое решение. boost::regex
поддерживает именно то, что вы просите, через его Boost-Extended Format String Syntax.
Таким образом, вы можете заменить шаблон:
(?<name1>John)|(?<name2>Mary)|(?<name3>Jake)
С строкой замены:
(?{name1}Joseph:(?{name2}Jessica:Keith))
И конечно, это работает. Вы можете проверить его в Notepad ++, но вот некоторые примеры кода:
#include <string>
#include <iostream>
#include <boost/regex.hpp>
int main(int argc, char **argv) {
std::string subject("John loves Mary, Mary loves Jake and Jake doesn't care about John and Mary.");
const char* replacement = "(?{name1}Joseph:(?{name2}Jessica:Keith))";
boost::regex re("(?<name1>John)|(?<name2>Mary)|(?<name3>Jake)", boost::match_perl);
std::string result = boost::regex_replace(subject, re, replacement, boost::format_all);
std::cout << result << std::endl;
return 0;
}
PCRE2
PCRE catched up с Boost, и ввел богатый синтаксис подстановки через PCRE2_SUBSTITUTE_EXTENDED
. Начиная с этого поста (v10.20), этот код еще не выпущен, но он доступен в исходном репозитории (версия 381), поэтому, если вам нужно это решение сейчас, вам придется построить PCRE2 из источника.
картина та же, но строка замены имеет другой синтаксис:
${name1:+Joseph:${name2:+Jessica:Keith}}
Вот некоторые примеры C код:
#include <stdio.h>
#include <string.h>
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
int main(int argc, char **argv) {
int error;
PCRE2_SIZE erroffset;
const PCRE2_SPTR pattern = (PCRE2_SPTR)"(?<name1>John)|(?<name2>Mary)|(?<name3>Jake)";
const PCRE2_SPTR subject = (PCRE2_SPTR)"John loves Mary, Mary loves Jake and Jake doesn't care about John and Mary.";
const PCRE2_SPTR replacement = (PCRE2_SPTR)"${name1:+Joseph:${name2:+Jessica:Keith}}";
pcre2_code *re = pcre2_compile(pattern, PCRE2_ZERO_TERMINATED, 0, &error, &erroffset, 0);
if (re == 0)
return 1;
pcre2_jit_compile(re, PCRE2_JIT_COMPLETE);
PCRE2_UCHAR output[1024] = "";
PCRE2_SIZE outlen = sizeof(output)/sizeof(PCRE2_UCHAR);
int rc = pcre2_substitute(re, subject, PCRE2_ZERO_TERMINATED, 0, PCRE2_SUBSTITUTE_GLOBAL | PCRE2_SUBSTITUTE_EXTENDED, 0, 0, replacement, PCRE2_ZERO_TERMINATED, output, &outlen);
if (rc >= 0)
printf("%s\n", output);
pcre2_code_free(re);
return 0;
}
PCRE
С PCRE (< v10), не повезло тебе. В нем отсутствует функция замены, это остается для разработчика.
... это означает, что если это библиотека, которую вы используете, вы все равно будете иметь полный контроль над процессом замещения. Вы можете использовать шаблон, такие как:
John(*MARK:1)|Mary(*MARK:2)|Jake(*MARK:3)
А потом, заменить на дискриминацию на последний встречается MARK
.
Qt
QRegularExpression
класс в Qt инкапсулирует библиотеку PCRE (не PCRE2), но это, похоже, не подвергать все функции PCRE.
Во всяком случае, QString::replace
overload который принимает QRegularExpression
не выглядит так, как это полнофункциональный:
QString & QString::replace(const QRegularExpression & re, const QString & after)
Таким образом, вы по своему усмотрению здесь.
Мои 2 цента
Эй, может быть такой простой замены, регулярное выражение является излишеством ... Если у вас есть проблемы с производительностью, вы должны попытаться реализовать эти замены вручную - тщательно разработанный алгоритм должен быстрее, чем регулярное выражение. Просто убедитесь, что вы прокомментируете свой код и посмотрите, где находится преступник.
Вы не можете использовать шаблон регулярного выражения в заменяющей строке или какие-либо условия. Тогда вам нужен обратный вызов. –
@stribizhev не обязательно, некоторые библиотеки предоставляют такую возможность (см. Мой ответ) ;-) –