Как захватить 0-2 группы в регулярных выражениях C ++ и распечатать их?

Edit 3

Я перешел к хорошему подходу к пользовательскому синтаксическому анализу, так как застрял с регулярным выражением. Это оказалось не так уж и плохо, так как содержимое файла может быть аккуратно разбито на токены, а токены могут быть проанализированы в цикле сvery простой конечный автомат. Для тех, кто хочет проверить, есть фрагмент кода, который делает это с помощью range-for, ifstream итераторов и пользовательского потокового токенизатора, на мой другой вопрос в StackoverflowВот, Эти методы значительно уменьшают сложность создания пользовательского парсера.

Я хотел бы разбить содержимое файла в первой части на группы по два, а затем просто построчно. Мне нравится полуфункциональное решение, но я хотел бы узнать, как сделать это лучше. То есть без «дополнительной обработки» восполнить мое отсутствие знаний с помощью групп захвата. Далее несколько предварительных и, в конце концов, более точный вопрос (строка

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

... это тот, о котором я хотел бы спросить в сочетании с обработкой его результатов).

Файлы, которые в основном определены так:

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]

Где каждая из строк данных состоит из определенного числа целых чисел или чисел с плавающей запятой, разделенных пробелом. Каждая строка имеет столько же чисел, сколько и другие (например, каждая строка может иметь четыре целых числа). Итак, «раздел интерпретации» в основном говорит этот формат в виде простого текста в одну строку.

У меня есть почти рабочее решение, которое читает такие файлы, как это:

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;
}

С регулярным выражениемexpressionТеперь он печатает<value> части файла определения, затем часть интерпретации, а затем строки данных по одной. Если я изменю регулярное выражение на

"([^:]+?)(:|$)"

... он печатает все строки, разбитые на группы по одной, почти как я хотел бы, но как разбить первую часть на группы по две, а остальные построчно?

Любые указатели, код, объяснения действительно приветствуются. Благодарю.

EDIT:

Как отмеченоTom Kerr уже, но некоторые дополнительные моменты, это также репетиция или кодирование ката, если хотите, чтобы не писать собственный анализатор, а чтобы посмотреть, смогу ли я - или мы могли бы :-) - выполнить это с помощью регулярных выражений. Я знаю, что регулярное выражение - не самая эффективная вещь, которую нужно здесь делать, но это не имеет значения.

Я надеюсь получить что-то вроде списка кортежей информации заголовка (кортеж размера 2), затем строку INTERPRET (кортеж размера 1), которую я мог бы использовать, чтобы выбрать функцию, связанную с данными. линии (кортеж размера 1).

Да, "Как интерпретировать" строка содержится в наборе четко определенных строк, и я мог просто читать строку за строкой с начала, разбивая строки по пути, пока не встретится одна из строк INTERPRET. Я знаю, что это регулярное решение - не самый эффективный метод, но больше похоже на кодирование kata, чтобы заставить себя писать что-то иное, чем анализаторы клиентов (и довольно давно я писал на C ++ в последний раз, так что это репетиция иначе тоже).

EDIT 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;
}

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

Ответы на вопрос(1)

Ваш ответ на вопрос