Подтвердить что ты не робот

Является ли это С++ 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") тоже не работает.

4b9b3361

Ответ 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 он работает как ожидалось.