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

Редактировать 3

Я перешел к старому доброму пользовательскому подходу к синтаксическому анализу, когда застрял с регулярным выражением. Это оказалось не так уж и плохо, так как содержимое файла можно довольно аккуратно разбить на токены, а токены можно анализировать в цикле с помощью очень простого конечного автомата. Те, кто хочет проверить, есть фрагмент кода, делающий это с диапазоном -для итераторов 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, он теперь печатает части файла определения, затем часть интерпретации, а затем строки данных одну за другой. Если я изменю регулярное выражение на

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

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

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

РЕДАКТИРОВАТЬ:

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

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

Да, строка «КАК ИНТЕРПРЕТИТЬ» содержится в наборе хорошо -определенных строк, и я мог бы просто читать строку за строкой с самого начала, разбивая строки по пути, пока не встретится одна из строк ИНТЕРПРЕТ. Я знаю, что это решение с регулярными выражениями не самый эффективный метод, но больше похоже на кодирование ката, чтобы заставить себя писать что-то еще, чем клиентские синтаксические анализаторы (, и в последний раз я писал на 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;
}

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

8
задан Community 23 May 2017 в 12:00
поделиться