Проблема с регуляркой

133
07 мая 2019, 08:50

Есть регулярное выражение:

(?:\[([а-я ]+)(?:,([а-я ]+)-([а-я ]+))*\])

Есть текст:

[тут ок,это-не матчит,это-матчит]

Надо чтобы в итоге матчило следующие группы:

  • тут ок
  • это
  • не матчит
  • это
  • матчит

Однако на деле получаю только последнюю пару после запятой ,X-X, а то, что перед ней - не матчит. То есть для этого текста матчит так:

  • тут ок
  • это
  • матчит

А надо, чтобы все пары ,(X-X),(X-X),(X-X), ... (X-X)] добавлялись в разные группы.

Для проверки использую удобный сервис https://regexr.com/, если хотите быстро протестировать, что действительно не работает.

Как изменить регулярку, чтобы получить требуемое поведение? Использую std::regex_constants::ECMAScript | std::regex_constants::collate грамматику.

Answer 1

Повторяющиеся захватывающие группы всегда сохраняют последнее захваченное значение. В C# и Python PyPi regex есть возможность получить все захваченные значения, есть такая опция и в Boost, но там её лучше не использовать. В C++ используйте два регулярных выражения, сначала ваше для предварительной валидации строки, а потом её часть для получения всех вхождений.

Регулярное выражение для валидации строки:

^\[[а-я ]+(?:,[а-я ]+-[а-я ]+)*]$

Демо онлайн

Регулярное выражение для нахождения всех совпадений:

[а-я -]+

Демо онлайн

Пример кода:

#include <string>
#include <vector>
#include <regex>
// ...
std::regex val_rx(R"(\[[а-я ]+(?:,[а-я ]+-[а-я ]+)*\])");
std::regex extract_rx("[а-я -]+");
std::string foo = "[тут ок,это-не матчит,это-матчит]";
if (std::regex_match(foo.begin(), foo.end(), val_rx)) {
    std::vector<std::string> result(std::sregex_token_iterator(foo.begin(), foo.end(), extract_rx),
                                   std::sregex_token_iterator());
}
READ ALSO
Включение библиотек в проект cmake

Включение библиотек в проект cmake

Осваиваю cmake и столкнулся вот с какой проблемой: У меня есть три папки с написанными мною статическими библиотекамиНазовем их a, b и c

149
Ошибка при работе с вектором std::bad_alloc

Ошибка при работе с вектором std::bad_alloc

Из-за чего такая ошибка? И как её исправить?

139
Почему возникает ошибки при установки java-alternatives?

Почему возникает ошибки при установки java-alternatives?

Хочу что бы JDK11 был выбран, по умолчанию, вручнуюВвожу команду:

151