C ++ 11正则表达式匹配捕获组多次

时间:2016-09-08 20:08:43

标签: c++ regex c++11 ecmascript-5

有人可以帮我在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

1 个答案:

答案 0 :(得分:1)

使用std::regex,当将某个字符串与连续的重复模式相匹配时,您将无法保持多重重复捕获。

您可能要做的是匹配包含前缀和重复块的整体文本,将后者捕获到一个单独的组中,然后使用第二个较小的正则表达式来分别捕获所有想要的子字符串。

这里的第一个正则表达式可能是

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

请参见online demo。它将与hw-descriptor((?::[pmu][^^]*\\^)+)匹配,并将:[pmu][^^]*\^模式的一个或多个重复捕获到组1::p / m / { {1}},除了u以外的0个或更多字符,然后为^。找到匹配项后,使用^正则表达式返回所有真实的“匹配项”。

C++ demo

:[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;
    }
}
相关问题