Найти только первое соответствие std :: regex - PullRequest
0 голосов
/ 06 февраля 2019

Я пытаюсь найти эффективный способ жадно найти первое совпадение для std::regex без анализа всего ввода.

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

Итак, предположим простое, скажем,

std::regex integralRegex = std::regex("([+-]?[1-9]*[0-9]+)");

Есть ли способ найти самое длинное совпадение, начиная сначало ввода без сканирования всего этого?Похоже, std::regex_match пытается сопоставить весь ввод, в то время как std::regex_search принудительно находит все совпадения.

Возможно, мне не хватает тривиальной перегрузки для моей цели, но я не могу найти эффективное решение проблемы.

Просто чтобы прояснить вопрос: я не заинтересован в остановке после первого под-совпадения и игнорирую оставшуюся часть ввода, но для ввода, подобного "51+12*3" Я хотел бы что-то, что находит сначала 51матч, а затем останавливается, игнорируя все, что после.

1 Ответ

0 голосов
/ 06 февраля 2019

Прежде всего [+-]?[1-9]?[0-9]+ Я думаю, что это то же самое, но должно быть немного быстрее.Или вы намереваетесь использовать что-то вроде этого: [+-]?[1-9][0-9]*|0 (ноль без знака или число, не начинающееся с нуля).

Во-вторых, C ++ предоставляет итератор регулярного выражения:

const std::string s = "51+12*3";

std::regex number_regex("[+-]?[1-9]?[0-9]+");
auto words_begin = 
    std::sregex_iterator(s.begin(), s.end(), number_regex);
auto words_end = std::sregex_iterator();

std::cout << "Found " 
          << std::distance(words_begin, words_end) 
          << " numbers:\n";

for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
    std::smatch match = *i;                                                 
    std::string match_str = match.str(); 
    std::cout << match_str << '\n';
} 

И выглядит такэто то, что вам нужно.

https://wandbox.org/permlink/tkaAfIslkWeY2poo

...