2016-02-08 3 views
0

Хотелось бы думать, что на самом деле это не ошибка в стандартной библиотеке, но у меня заканчиваются места для поиска.std :: regex fatal error

Заявление std::regex(expression), где expression является строкой std ::, вызывает фатальную ошибку доступа к памяти.

expression объявляется утверждением:

std::string expression = std::string("^(") + 
    std::string("[\x09\x0A\x0D\x20-\x7E]|") + // ASCII 
    std::string("[\xC2-\xDF][\x80-\xBF]|") + // non-overlong 2-byte 
    std::string("\xE0[\xA0-\xBF][\x80-\xBF]|") + // excluding overlong 
    std::string("[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|") + // straight 3-byte 
    std::string("\xED[\x80-\x9F][\x80-\xBF]|") + // excluding surrogates 
    std::string("\xF0[\x90-\xBF][\x80-\xBF]{2}|") + // planes 1-3 
    std::string("[\xF1-\xF3][\x80-\xBF]{3}|") + // planes 4-15 
    std::string("\xF4[\x80-\x8F][\x80-\xBF]{2}") + // plane 16 
    ")*$"; 

Это регулярное выражение было взято из http://www.w3.org/International/questions/qa-forms-utf-8, чтобы проверить последовательность байт, является ли UTF-8.

На самом деле это ошибка в библиотеке, или я пропущу что-то действительно крошечное?

Составлено с VS2015 C++, если это имеет значение.

EDIT: Я забыл упомянуть, что в этом есть одна конкретная строка, которая разбивает код. std::string("[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|") + // straight 3-byte - единственная линия, которая ломается. прокомментируйте это, и все работает отлично. Эта строка сама по себе создает ошибку доступа к памяти.

+0

Вам нужно удвоить escape-обратную косую черту в неровном строковом литерале. Лучше всего использовать сырые строковые литералы. Попробуйте заменить все '\ x' на' \\ x'. –

+0

C++ требует, чтобы экраны были экранированы в строковых литералах, если не использовать новый синтаксис raw. – sln

+0

В этом примере вы используете сайт, он использует '\ A ,, \ z' по какой-то причине. Вы не должны использовать '^ .. $', поскольку это не то же самое. – sln

ответ

1

Таким образом, если вы используете побеги в строковых литералах, без использования сырца синтаксиса,
вы должны избежать побегов.

Пример, новая строка:

std::string expression = std::string("^(") + 
    std::string("[\\x09\\x0A\\x0D\\x20-\\x7E]|") + // ASCII 
    std::string("[\\xC2-\\xDF][\\x80-\\xBF]|") + // non-overlong 2-byte 
    std::string("\\xE0[\\xA0-\\xBF][\\x80-\\xBF]|") + // excluding overlong 
    std::string("[\\xE1-\\xEC\\xEE\\xEF][\\x80-\\xBF]{2}|") + // straight 3-byte 
    std::string("\\xED[\\x80-\\x9F][\\x80-\\xBF]|") + // excluding surrogates 
    std::string("\\xF0[\\x90-\\xBF][\\x80-\\xBF]{2}|") + // planes 1-3 
    std::string("[\\xF1-\\xF3][\\x80-\\xBF]{3}|") + // planes 4-15 
    std::string("\\xF4[\\x80-\\x8F][\\x80-\\xBF]{2}") + // plane 16 
    ")*$"; 

Если вы не избежать их, компилятор пытается интерпретировать его как
особый характер. В этом случае он интерпретирует их как шестнадцатеричные двоичные символы.

И, в то время как движок регулярных выражений, вероятно, получает правильный характер,
всегда лучше передать гекс к двигателю, так что вы можете увидеть характер
, которые могли бы нарушить его (если он делает).

+0

объясняет, почему только одна строка вылетает из программы? Я могу прокомментировать строку, которая разбивает ее, оставляя одну косую черту во всех остальных, и код будет работать нормально. Хотя информация с двойной косой чертой хорошо знать, она не фиксирует тот факт, что программа выйдет из строя. – James

+0

Подождите секунду. Я использую VS2010, я собираюсь запустить вашу строку ascii и посмотреть, сработает ли она. Может быть проблемой триграфа. – sln

+0

Я получаю это в отладчике '^ ([\t - ~] | [Â-ß] [€ -¿] | à [-¿] [€ -¿] | [á- Iii] [€ -¿] {2} | I [€ -Y] [€ -¿] | D [-¿] [€ -¿] {2} | [N-O] [€ -¿] {3} | ô [€ -] [€ -¿] {2}) * $ 'и это не разбивает мое приложение. – sln