#c #regex
#c #регулярное выражение
Вопрос:
С сегодняшнего появления кода у нас были входные данные, которые могли быть списком из нескольких пакетов.
"3 drab lime bags, 1 drab plum bag, 2 vibrant tomato bags, 1 plaid blue bag.";
Например, в моем вводе была строка, подобная.
Что я сделал, чтобы решить эту проблему: разделите его среди ','
, а затем примените std::regex bag_regex("([0-9] ) (\w \w ) bag");
к каждой из этих подстрок.
Теперь я попробовал, смогу ли я сделать это, возможно, за один присест или что-то в этом роде, и попытался использовать https://en.cppreference.com/w/cpp/regex/regex_token_iterator вместо этого.
Пример кода:
std::string test = "3 drab lime bags, 1 drab plum bag, 2 vibrant tomato bags, 1 plaid blue bag.";
std::regex bag_regex_it("[0-9] \w \w ");
std::copy(std::sregex_token_iterator(test.begin(), test.end(), bag_regex_it, -1),
std::sregex_token_iterator(),
std::ostream_iterator<std::string>(std::cout, "n"));
Что я на самом деле получаю в своем выводе:
bags,
bag,
bags,
bag.
Есть ли какой-либо способ получить его уже в группах (количество номеров и описание цвета)? Я предполагаю, что правильное использование лямбда-выражения помогло бы здесь, но я понятия не имею, как это сделать. Идеальным результатом было std::vector
бы std::pair<int, std::string>
, например, содержащее проанализированную информацию, но этот код мне недоступен.
Комментарии:
1. Удалите
-1
аргумент в концеstd::sregex_token_iterator(test.begin(), test.end(), bag_regex_it, -1),
.-1
означает, что вам нужно получить все те части строки, которые НЕ совпадают , см. ideone.com/mxd8Z1
Ответ №1:
Вы можете использовать последний параметр в regex_token_iterator
качестве массива подгрупп (учитывая 2 группы (количество и цвет), которые вы хотите).
Следующий фрагмент не выполняет никакой проверки ошибок и предполагает, что введенная вами строка является допустимой:
using Pair = std::pair<int, std::string>;
Pair p;
const int subgroups[] = {1,2};
std::vector < Pair> results; // Your desired result
std::regex_token_iterator<std::string::iterator> c
{ test.begin(), test.end(), regex_it, subgroups };
std::regex_token_iterator<std::string::iterator> rend;
while (c!=rend) {
// Do some sort of error handling here
p.first = std::stoi(*c );
p.second = *c ;
results.push_back(p);
}
std::cout << results.size(); // 4