有人可以帮我在C ++ 11中使用JavaScript(ECMAScript)正则表达式在:和^符号之间提取文本。我不需要捕获hw-descriptor
本身 - 但它必须存在于该行中,以便将该行的其余部分视为匹配。此外,:p....^
,:m....^
和:u....^
可以按任意顺序到达,且必须至少有1个人在场。
我尝试使用以下正则表达式:
static const std::regex gRegex("(?:hw-descriptor)(:[pmu](.*?)\\^)+", std::regex::icase);
针对以下文字行:
"hw-descriptor:pTEXT1^:mTEXT2^:uTEXT3^"
以下是发布在 live coliru 上的代码。它显示了我如何尝试解决这个问题,但是我只获得了1个匹配。我需要看看如何提取对应于前面描述的p m或u字符的每个潜在的3个匹配。
#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 :(得分:1)
使用std::regex
,当将某个字符串与连续的重复模式相匹配时,您将无法保持多重重复捕获。
您可能要做的是匹配包含前缀和重复块的整体文本,将后者捕获到一个单独的组中,然后使用第二个较小的正则表达式来分别捕获所有想要的子字符串。
这里的第一个正则表达式可能是
hw-descriptor((?::[pmu][^^]*\\^)+)
请参见online demo。它将与hw-descriptor
和((?::[pmu][^^]*\\^)+)
匹配,并将:[pmu][^^]*\^
模式的一个或多个重复捕获到组1::
,p
/ m
/ { {1}},除了u
以外的0个或更多字符,然后为^
。找到匹配项后,使用^
正则表达式返回所有真实的“匹配项”。
:[pmu][^^]*\^
输出:
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;
}
}