Понимание регулярных выражений в C ++ 11

Я пытаюсь выучить регулярные выражения в C ++ 11.
Должно быть, что-то не так, потому что никакие скобки или escape-последовательности не работают.

Вот мой код:

#include <iostream>
#include <regex>
#include <string>

using namespace std;

int main()
{
try
{
cout << R"(\d*(\.\d*)?;)" << endl << endl;

regex rx{ R"(\d*(\.\d*)?;)", regex_constants::ECMAScript };
smatch m;

if( regex_match( string( "10;20;30;40;" ), m, rx ) )
{
cout << m[0];
}
}
catch( const regex_error &e )
{
cerr << e.what() << ". Code: " << e.code() << endl;

switch( e.code() )
{
case regex_constants::error_collate:
cerr << "The expression contained an invalid collating element name.";
break;
case regex_constants::error_ctype:
cerr << "The expression contained an invalid character class name.";
break;
case regex_constants::error_escape:
cerr << "The expression contained an invalid escaped character, or a trailing escape.";
break;
case regex_constants::error_backref:
cerr << "The expression contained an invalid back reference.";
break;
case regex_constants::error_brack:
cerr << "The expression contained mismatched brackets ([ and ]).";
break;
case regex_constants::error_paren:
cerr << "The expression contained mismatched parentheses (( and )).";
break;
case regex_constants::error_brace:
cerr << "The expression contained mismatched braces ({ and }).";
break;
case regex_constants::error_badbrace:
cerr << "The expression contained an invalid range between braces ({ and }).";
break;
case regex_constants::error_range:
cerr << "The expression contained an invalid character range.";
break;
case regex_constants::error_space:
cerr << "There was insufficient memory to convert the expression into a finite state machine.";
break;
case regex_constants::error_badrepeat:
cerr << "The expression contained a repeat specifier (one of *?+{) that was not preceded by a valid regular expression.";
break;
case regex_constants::error_complexity:
cerr << "The complexity of an attempted match against a regular expression exceeded a pre-set level.";
break;
case regex_constants::error_stack:
cerr << "There was insufficient memory to determine whether the regular expression could match the specified character sequence.";
break;
default:
cerr << "Undefined.";
break;

}

cerr << endl;
}

return 0;
}

Выход:

\ Д * (. \ Д *) ?;

regex_error. Код: 2

Выражение содержало недопустимый экранированный символ или завершающий экранирующий символ.

Что я делаю неправильно?

Обновить

gcc версия 4.8.2 20131212 (Red Hat 4.8.2-7) (GCC)

Clang версия 3.3 (теги / RELEASE_33 / финал)

libstdc ++ версия 4.8.2

Решение

Что ж. Я читаю «Язык программирования C ++» и хотел поэкспериментировать с материалом std :: regex. Поэтому я думаю, что решение состоит в том, чтобы ждать gcc-4.9.

Я дал EagleV_Attnam кредит за указание на другие ошибки в моем коде.

4

Решение

Две вещи:

  1. Ваша строка "10;20;30;40;"определяется только в match_regex вызов. smatchв отличие от cmatch, ожидает строку (как в, тот, созданный string()) быть еще живым к тому времени, когда вы захотите получить к нему доступ.
  2. Ваше текущее регулярное выражение не соответствует (по крайней мере, не в моей системе). Он пытается соответствовать всей строке. Добавление. * В конце (и начало, но это не обязательно в вашем случае) должно исправить это, как если бы все повторялось (с R"((stuff)*)")

Рабочий код (но не смог попробовать его на gcc):

regex rx{ R"(\d*(\.\d*)?;.*)", regex_constants::ECMAScript };
smatch m;
string s("10;20;30;40;");
if (regex_match(s, m, rx))
{
cout << m[0];
}

Не знаю, исправит ли это вашу конкретную ошибку — я боюсь, что KitsuneYMG прав на это — но это не должно повредить, чтобы попытаться.

1

Другие решения

Одна проблема с вашим регулярным выражением — вы не экранируете \, и \ d не является допустимой escape-последовательностью в контексте строки. Я не уверен, что вы можете использовать идентификатор R в строке, но он для меня не определен.

Кроме того, регулярное выражение GCC было неполным в прошлый раз, когда я проверял. Так что вы можете быть вынуждены использовать регулярное выражение boost.

    regex rx( "\\d*;" ); //regexp, must escape '\'
string input = "10;20;30;40;";
smatch m;

if( regex_search( input, m, rx ) )
{
cout << m[0] << endl;
}
-2

По вопросам рекламы [email protected]