C ++ 11 регулярное выражение совпадает с группой захвата несколько раз

Может кто-нибудь помочь мне извлечь текст между символами: и ^ с помощью регулярного выражения JavaScript (ECMAScript) в C ++ 11. Мне не нужно захватывать hw-descriptor сам по себе — но он должен присутствовать в строке, чтобы остальная часть строки была рассмотрена на совпадение. Так же :p....^, :m....^ а также :u....^ может прибыть в любом порядке и должен быть как минимум 1 подарок.

Я попытался использовать следующее регулярное выражение:

static const std::regex gRegex("(?:hw-descriptor)(:[pmu](.*?)\\^)+", std::regex::icase);

напротив следующей текстовой строки:

"hw-descriptor:pTEXT1^:mTEXT2^:uTEXT3^"

Вот код, который размещен на живая колиру. Это показывает, как я пытался решить эту проблему, однако я получаю только 1 матч. Мне нужно посмотреть, как извлечь каждое из 3 возможных совпадений, соответствующих символам p m или u, описанным ранее.

#include <iostream>
#include <string>
#include <vector>
#include <regex>

int main()
{
static const std::regex gRegex("(?:hw-descriptor)(:[pmu](.*?)\\^)+", std::regex::icase);
std::string foo = "hw-descriptor:pTEXT1^:mTEXT2^:uTEXT3^";
// I seem to only get 1 match here, I was expecting
// to loop through each of the matches, looks like I need something like
// a pcre global option but I don't know how.
std::for_each(std::sregex_iterator(foo.cbegin(), foo.cend(), gRegex), std::sregex_iterator(),
[&](const auto& rMatch) {
for (int i=0; i< static_cast<int>(rMatch.size()); ++i) {
std::cout << rMatch[i] << std::endl;
}
});
}

Вышеуказанная программа дает следующий вывод:

g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
hw-descriptor:pTEXT1^:mTEXT2^:uTEXT3^
:uTEXT3^
TEXT3

0

Решение

С std::regexВы не можете сохранить повторные захваты с множеством повторов при сопоставлении определенной строки с последовательными повторяющимися образцами.

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

Первое регулярное выражение здесь может быть

hw-descriptor((?::[pmu][^^]*\\^)+)

Увидеть онлайн демо. Будет соответствовать hw-descriptor а также ((?::[pmu][^^]*\\^)+) включит в группу 1 одно или несколько повторений :[pmu][^^]*\^ шаблон: :, p/m/u, 0 или более символов, кроме ^ а потом ^, Найдя совпадение, используйте :[pmu][^^]*\^ регулярное выражение, чтобы вернуть все реальные «совпадения».

C ++ demo:

static const std::regex gRegex("hw-descriptor((?::[pmu][^^]*\\^)+)", std::regex::icase);
static const std::regex lRegex(":[pmu][^^]*\\^", std::regex::icase);
std::string foo = "hw-descriptor:pTEXT1^:mTEXT2^:uTEXT3^ hw-descriptor:pTEXT8^:mTEXT8^:uTEXT83^";
std::smatch smtch;
for(std::sregex_iterator i = std::sregex_iterator(foo.begin(), foo.end(), gRegex);
i != std::sregex_iterator();
++i)
{
std::smatch m = *i;
std::cout << "Match value: " << m.str() << std::endl;
std::string x = m.str(1);
for(std::sregex_iterator j = std::sregex_iterator(x.begin(), x.end(), lRegex);
j != std::sregex_iterator();
++j)
{
std::cout << "Element value: " << (*j).str() << std::endl;
}
}

Выход:

Match value: hw-descriptor:pTEXT1^:mTEXT2^:uTEXT3^
Element value: :pTEXT1^
Element value: :mTEXT2^
Element value: :uTEXT3^
Match value: hw-descriptor:pTEXT8^:mTEXT8^:uTEXT83^
Element value: :pTEXT8^
Element value: :mTEXT8^
Element value: :uTEXT83^
1

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

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector