В настоящее время я пытаюсь сделать регулярное выражение, которое соответствует параметрам URL и извлекает их.
Например, если я получил следующую строку параметров ?param1=someValue¶m2=someOtherValue
, std::regex_match
следует извлечь следующее содержимое:
param1
some_content
param2
some_other_content
Попробовав различные шаблоны регулярных выражений, я наконец-то создал шаблон, соответствующий тому, что хочу: std::regex("(?:[\\?&]([^=&]+)=([^=&]+))*")
,
Если я возьму предыдущий пример, std::regex_match
соответствует, как ожидалось. Однако он не извлекает ожидаемые значения, сохраняя только последние зафиксированные значения.
Например, следующий код:
std::regex paramsRegex("(?:[\\?&]([^=&]+)=([^=&]+))*");
std::string arg = "?param1=someValue¶m2=someOtherValue";
std::smatch sm;
std::regex_match(arg, sm, paramsRegex);
for (const auto &match : sm)
std::cout << match << std::endl;
даст следующий вывод:
param2
someOtherValue
Как видите, param1 и его значение пропускаются и не фиксируются.
После поиска в Google, я обнаружил, что это связано с жадным захватом, и я изменил свое регулярное выражение в "(?:[\\?&]([^=&]+)=([^=&]+))\\*?"
для того, чтобы включить нежадный захват.
Это регулярное выражение хорошо работает, когда я пытаюсь Rubular но это не совпадает, когда я использую его в C ++ (std::regex_match
возвращает false и ничего не фиксируется).
Я пробовал разные std::regex_constants
варианты (различные грамматики регулярных выражений с помощью std::regex_constants::grep
, std::regex_constants::egrep
, …) но результат тот же.
Кто-нибудь знает, как сделать не жадный захват регулярных выражений в C ++?
Как Казимир и Ипполит объяснил в своем комментарий, Мне просто нужно:
std::regex_iterator
Это дает мне следующий код:
std::regex paramsRegex("[\\?&]([^=]+)=([^&]+)");
std::string url_params = "?key1=val1&key2=val2&key3=val3&key4=val4";
std::smatch sm;
auto params_it = std::sregex_iterator(url_params.cbegin(), url_params.cend(), paramsRegex);
auto params_end = std::sregex_iterator();
while (params_it != params_end) {
auto param = params_it->str();
std::regex_match(param, sm, paramsRegex);
for (const auto &s : sm)
std::cout << s << std::endl;
++params_it;
}
И вот вывод:
?key1=val1
key1
val1
&key2=val2
key2
val2
&key3=val3
key3
val3
&key4=val4
key4
val4
Оригинальное регулярное выражение (?:[\\?&]([^=&]+)=([^=&]+))*
был просто изменен на [\\?&]([^=]+)=([^&]+)
,
Затем, используя std::sregex_iterator
Я получаю итератор для каждой соответствующей группы (?key1=val1
, &key2=val2
…)
Наконец, позвонив std::regex_match
по каждой подстроке я могу получить значения параметров.
Попробуйте использовать match_results :: префикс / суффикс:
string match_expression("your expression");
smatch result;
regex fnd(match_expression, regex_constants::icase);
while (regex_search(in_str, result, fnd, std::regex_constants::match_any))
{
for (size_t i = 1; i < result.size(); i++)
{
std::cout << result[i].str();
}
in_str = result.suffix();
}