Создание корректного std::regex приводит к синтаксической ошибке
Проблема
Создание объекта std::regex приводит к синтаксическому исключению, однако ни я, ни онлайн сервисы не видят в инициализируемом выражении синтаксической ошибки.
Пример
#include <regex>
#include <iostream>
using namespace std;
int main() {
try {
regex R("^([^;]+);(?:\\s*([^=]+)=((?<q>\"?)([^\"]*)\\k<q>);?)*$", regex_constants::ECMAScript);
}
catch (const regex_error& e) {
cout << "regex_error caught: " << e.what() << '\n';
if (e.code() == regex_constants::error_brack) {
cout << "The code was error_brack\n";
}
}
return 0;
}
Вывод
regex_error caught: regex_error(error_syntax)
Примечания
- Без экранизации:
^([^;]+);(?:\s*([^=]+)=((?<q>"?)([^"]*)\k<q>);?)*$ - На regex101.com
Вопросы
- В чем причина возникновения этой проблемы?
- Если таки синтаксическая ошибка, то может вы знаете сервисы, помогающие находить таковые каверзы?
Ответы (1 шт):
Автор решения: Wiktor Stribiżew
→ Ссылка
Поддержка именнованных захватывающих групп в std::regex не реализована. Необходимо заменить их на нумерованные захватывающие группы.
Также, удобнее задавать регулярные выражения с помощью "сырых" строковых литералов, чтобы использовать только один символ обратной косой черты.
Объявление вашего выражения можно записать как
regex R(R"(^([^;]+);(?:\s*([^=]+)=((\"?)([^\"]*)\4);?)*$)");
Группа "q" заменена группой №4. R"(...)" — функциональная часть строкового литерала, сам шаблон находится внутри скобок.
См. пример работы кода на C++:
#include <regex>
#include <iostream>
using namespace std;
int main() {
try {
regex R(R"(^([^;]+);(?:\s*([^=]+)=((\"?)([^\"]*)\4);?)*$)");
string s("attached; filename=\"Hello, world!.docx\"");
smatch m;
if (regex_search(s, m, R)) {
std::cout << m[0] << std::endl;
}
}
catch (const regex_error& e) {
cout << "regex_error caught: " << e.what() << '\n';
if (e.code() == regex_constants::error_brack) {
cout << "The code was error_brack\n";
}
}
return 0;
}