Токенизация с двоеточием с использованием std::tr1::regex

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

Если я использую это выражение регулярного выражения в EditPad Pro 7.2.2, оно делает именно то , что я хочу. (([^: \ "'] | \" [^ \ "] \" |' [^ '] ') +)?

Например, используя эту строку данных::foo:::bar:baz

Я получаю 6 хитов: [пусто],foo,[пусто],[пусто], бар, баз

Все идет нормально. Однако в моем коде, используя std::tr1::regex, я получаю 9 совпадений с одной и той же строкой данных. Кажется, что я получаю дополнительный пустой удар после каждого непустого удара.

void RICommandState::InitRawCommandEnum(const std::string& full_command)
{
    // Split string by colons, but ignore text within quotes.
    static const std::tr1::regex split_by_colon("(([^:\"']|\"[^\"]*\"|'[^']*')+)?");

    raw_command_list.clear();
    raw_command_index = 0;

    DebugPrintf(ZONE_REMOTE, (TEXT("InitRawCommandEnum FULL '%S'"), full_command.c_str()));

    const std::tr1::sregex_token_iterator end;
    for (std::tr1::sregex_token_iterator it(full_command.begin(),
                                            full_command.end(),
                                            split_by_colon);
         it != end;
         it++)
    {
        raw_command_list.push_back(*it);
        const std::string temp(*it);
        DebugPrintf(ZONE_REMOTE, (TEXT("InitRawCommandEnum '%S'"), temp.c_str()));
    }

    DebugPrintf(ZONE_REMOTE, (TEXT("InitRawCommandEnum hits = %d"), raw_command_list.size()));
}

И вот мой вывод:

InitRawCommandEnum FULL ':foo:::bar:baz'
InitRawCommandEnum ''
InitRawCommandEnum 'foo'
InitRawCommandEnum ''
InitRawCommandEnum ''
InitRawCommandEnum ''
InitRawCommandEnum 'bar'
InitRawCommandEnum ''
InitRawCommandEnum 'baz'
InitRawCommandEnum ''
InitRawCommandEnum hits = 9

Самый важный вопрос заключается в том, как я могу заставить свой поиск регулярных выражений получать один (и только один) удар для каждого токена, разделенного двоеточием? Проблема с моим поисковым выражением?

Или, может быть, я неправильно понимаю результаты? Имеют ли пустые строки после непустых строк особое значение? Если да, то? И если это так, то является ли правильным решением просто игнорировать их?

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

Спасибо!

1 ответ

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

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

void RICommandState::InitRawCommandEnum(const std::string& full_command)
{
    // Split string by colons, but ignore text within quotes.
    static const std::tr1::regex split_by_colon("(?:[^:\"']|\"[^\"]*\"|'[^']*')*");

    raw_command_list.clear();
    raw_command_index = 0;

    std::tr1::sregex_iterator::difference_type minPosition = 0;
    const std::tr1::sregex_iterator end;
    for (std::tr1::sregex_iterator it(full_command.begin(),
                                      full_command.end(),
                                      split_by_colon);
         it != end;
         it++)
    {
        if (it->position() >= minPosition)
        {
            raw_command_list.push_back(it->str());
            minPosition = it->position() + it->length() + 1;
        }
    }
}
Другие вопросы по тегам