Является ли это С++ 11 regex ошибкой или компилятором?
ОК, это не оригинальная программа, в которой я столкнулся с этой проблемой, но я продублировал ее намного меньше. Очень простая проблема.
main.cpp:
#include <iostream>
#include <regex>
using namespace std;
int main()
{
regex r1("S");
printf("S works.\n");
regex r2(".");
printf(". works.\n");
regex r3(".+");
printf(".+ works.\n");
regex r4("[0-9]");
printf("[0-9] works.\n");
return 0;
}
Скомпилировано с этой командой успешно, никаких сообщений об ошибках:
$ g++ -std=c++0x main.cpp
Последняя строка g++ -v
, кстати, есть:
gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3)
И результат, когда я пытаюсь запустить его:
$ ./a.out
S works.
. works.
.+ works.
terminate called after throwing an instance of 'std::regex_error'
what(): regex_error
Aborted
Это происходит так же, если я меняю r4 на \\s
, \\w
или [a-z]
. Это проблема с компилятором? Возможно, я могу поверить, что движок регулярных выражений С++ 11 имеет разные способы сказать "пробел" или "символ слова", но квадратные скобки не работают. Это то, что было исправлено в 4.6.2?
EDIT:
Joachim Pileborg предоставил частичное решение, используя дополнительный параметр regex_constants
, чтобы включить синтаксис, поддерживающий квадратные скобки, но ни basic
, extended
, awk
, ни ECMAScript
, похоже, не поддерживают обратную косую черту, (\\s
, \\w
или \\t
).
ИЗМЕНИТЬ 2:
Использование исходных строк (R"(\w)"
вместо "\\w"
) тоже не работает.
Ответы
Ответ 1
Обновление: <regex>
теперь реализовано и выпущено в GCC 4.9.0
Старый ответ:
Синтаксис ECMAScript принимает [0-9]
, \s
, \w
и т.д., см. ECMA-262 (15.10). Вот пример с boost::regex
, который по умолчанию использует синтаксис ECMAScript:
#include <boost/regex.hpp>
int main(int argc, char* argv[]) {
using namespace boost;
regex e("[0-9]");
return argc > 1 ? !regex_match(argv[1], e) : 2;
}
Работает:
$ g++ -std=c++0x *.cc -lboost_regex && ./a.out 1
В соответствии со стандартом С++ 11 (28.8.2) basic_regex()
по умолчанию используется флаг regex_constants::ECMAScript
, поэтому он должен понимать этот синтаксис.
Является ли это ошибка регулярного выражения С++ 11 или компилятором?
gcc-4.6.1 не поддерживает регулярные выражения С++ 11 (28.13).
Ответ 2
Ошибка заключается в том, что по умолчанию для создания регулярного выражения используется синтаксис ECMAScript для выражения, который не поддерживает скобки. Вы должны объявить выражение с флагом basic
или extended
:
std::regex r4("[0-9]", std::regex_constants::basic);
Изменить Похоже, что libstdС++ (часть GCC и библиотека, которая обрабатывает все материалы С++) еще не полностью реализуют регулярные выражения. В своем статусном документе говорят, что модифицированная грамматика регулярного выражения ECMAScript еще не реализована.
Ответ 3
Поддержка регулярных выражений улучшилась между gcc 4.8.2 и 4.9.2. Например, регулярное выражение =[A-Z]{3}
не срабатывало для меня:
Ошибка регулярного выражения
После обновления до gcc 4.9.2 он работает как ожидалось.