Токенизация с двоеточием с использованием 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;
}
}
}