如何在C++正则表达式中捕获0-2组并打印它们?

Vek*_*ksi 8 c++ regex c++11

编辑3

当我遇到正则表达式时,我转向了good'ol自定义解析方法.它并没有那么糟糕,因为文件内容可以非常巧妙地进行标记,并且可以使用非常简单的状态机在循环中解析标记.谁想要检查,还有的代码区间为,ifstream的迭代器和自定义的流标记者在#1我的其他问题这样一个片段在这里.这些技术大大降低了自定义解析器的复杂性.

我想在第一部分中将文件内容标记为两个捕获组,然后逐行标记.我喜欢半功能解决方案,但我想学习如何做得更好.也就是说,没有"额外处理"来弥补我对捕获组的缺乏知识.接下来是一些预赛,最后是一个更确切的问题(线路

const std::regex expression("([^:]+?)(^:|$)");
Run Code Online (Sandbox Code Playgroud)

...是我想要询问的与处理结果相关的那个).

基本上定义的文件如下:

definition_literal : value_literal
definition_literal : value_literal
definition_literal : value_literal
definition_literal : value_literal
HOW TO INTERPRET THE FOLLOWING SECTION OF ROWS
[DATA ROW 1]
[DATA ROW 2]
...
[DATA ROW n]
Run Code Online (Sandbox Code Playgroud)

其中每个数据行由一定数量的整数或由空格分隔的浮点数组成.每行具有与其他行一样多的数字(例如,每行可以具有四个整数).因此,"解释部分"基本上以一行的纯文本形式告诉这种格式.

我有一个几乎可以工作的解决方案,读取这样的文件:

int main() 
{
    std::ifstream file("xyz", std::ios_base::in);
    if(file.good())
    {
        std::stringstream file_memory_buffer;
        file_memory_buffer << file.rdbuf();
        std::string str = file_memory_buffer.str(); 
        file.close();

        const std::regex expression("([^:]+?)(^:|$)");
        std::smatch result;

        const std::sregex_token_iterator end;       
        for(std::sregex_token_iterator i(str.begin(), str.end(), expression); i != end; ++i)
        {
            std::cout << (*i) << std::endl;
        }
    }

    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

定义了正则表达式后expression,它现在打印<value>定义文件的各个部分,然后是解释部分,然后逐个打印数据行.如果我将正则表达式更改为

"([^:]+?)(:|$)"
Run Code Online (Sandbox Code Playgroud)

...它打印出所有标记为一组的行,几乎就像我想要的那样,但是如何将第一部分分成2组,其余部分逐行标记?

任何指针,代码,解释都是真正受欢迎的.谢谢.

编辑:

正如汤姆克尔已经注意到的,但是还有一些额外的观点,这也是排练,或编码kata,如果你愿意,不写自定义解析器,但看看我是否可以 - 或者我们可以:-) - 完成这与正则表达式.我知道正则表达式不是最有效的方法,但这并不重要.

我希望有的是一个标题信息元组列表(大小为2的元组),然后是INTERPRET行(大小为1的元组),我可以用它来选择一个关于如何处理数据的函数行(大小为1的元组).

是的,"HOW TO INTERPRET"行包含在一组明确定义的字符串中,我可以从头开始逐行读取,沿途分割字符串,直到满足其中一条INTERPRET行.我知道,这个正则表达式解决方案不是最有效的方法,但更像编码kata让自己编写除客户解析器以外的其他内容(而且我最近一次用C++编写,所以这也是排练).

编辑2

我已经设法通过更改迭代器类型来访问元组(在此问题的上下文中),就像这样

const std::sregex_iterator end;     
for(std::sregex_iterator i(str.begin(), str.end(), expression); i != end; ++i)
{
    std::cout << "0: " << (*i)[0] << std::endl;
    std::cout << "1: " << (*i)[1] << std::endl;
    std::cout << "2: " << (*i)[2] << std::endl;
    std::cout << "***" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

虽然这仍然不像我想要的那样,但我正在尝试使用的正则表达式出现了问题.无论如何,这种新的发现,另一种迭代器,也有帮助.

Tom*_*err 1

我相信您正在尝试的是:

TEST(re) {
    static const boost::regex re("^([^:]+) : ([^:]+)$");

    std::string str = "a : b";
    CHECK(boost::regex_match(str, re));
    CHECK(!boost::regex_match("a:a : bbb", re));
    CHECK(!boost::regex_match("aaa : b:b", re));

    boost::smatch what;
    CHECK(boost::regex_match(str, what, re, boost::match_extra));
    CHECK_EQUAL(3, what.size());
    CHECK_EQUAL(str, what[0]);
    CHECK_EQUAL("a", what[1]);
    CHECK_EQUAL("b", what[2]);
}
Run Code Online (Sandbox Code Playgroud)

但我不确定在这种情况下我会推荐正则表达式。我认为您会发现只需一次阅读一行,拆分:,然后修剪空格就更容易管理。

我想如果你不能依赖下面的行作为哨兵,那么事情会更困难。通常我希望这样的格式从该行中显而易见,而不是标题的每一行的格式。

HOW TO INTERPRET THE FOLLOWING SECTION OF ROWS
Run Code Online (Sandbox Code Playgroud)