2016-11-05 2 views
0

При разработке моей личной библиотеки я наткнулся на то, что, по моему мнению, является ошибкой внутри libstdC++ 6.Подтверждение ошибки

Потому что я уверен, что эта библиотека была рассмотрена многими людьми с гораздо более высоким уровнем квалификации, чем я. Я пришел сюда, чтобы подтвердить мои выводы и получить помощь в дальнейших шагах.

Рассмотрим следующий код:

#include <regex> 
#include <iostream> 

int main() 
{ 
     std::string uri = "http://example.com/test.html"; 
     std::regex reg(...); 
     std::smatch match; 
     std::regex_match(uri, match, reg); 
     for(auto& e: match) 
     { 
       std::cout<<e.str() <<std::endl; 
     } 
} 

Я написал регулярное выражение для разбора URL в

  • протокола
  • пользователя/Pass (по желанию)
  • Хост
  • Порт (опционально)
  • Путь (по желанию)
  • запрос (необязательно)
  • Местонахождение (факультативно)

Я использовал следующее регулярное выражение (в C++):

std::regex reg("^(.+):\\/\\/([email protected])?([a-zA-Z\\.\\-0-9]+)(:\\d{1,5})?([^?\\n\\#]*)(\\?[^#\\n]*)?(\\#.*)?$"); 

Это работало довольно хорошо в онлайн-тестером и MSVC++ 2015 Update 3 но сбой на моем хосте сборки, где хост-часть соответствует хосту и пути.

Buildhost:

г ++ (Ubuntu 5.4.0-6ubuntu1 ~ 16.04.2) 5.4.0 20160609

libstdC++ 6: amd64 5.4.0-6ubuntu1 ~ 16.04.2

Я считаю, что это ошибка, потому что, если изменить регулярное выражение для этого:

std::regex reg("^(.+):\\/\\/([email protected])?([a-zA-Z\\.0-9\\-]+)(:\\d{1,5})?([^?\\n\\#]*)(\\?[^#\\n]*)?(\\#.*)?$"); 

Он отлично работает хотя он должен вести себя точно так же.

В противном случае регулярное выражение: https://ideone.com/7n2JdK

Работа регулярных выражений: https://ideone.com/6NMPUW

ли я пропустить что-то очень важное здесь, или это ошибка в libstdC++ 6?

Единственное отличие состоит в классе полукокса:

[a-zA-Z\\.\\-0-9] // not working 
[a-zA-Z\\.0-9\\-] // working 
+0

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

+0

Нет необходимости проверять символ char. Это явно ошибка. –

ответ

0

Это явно ошибка, потому что "[.\\-0]" должен быть проанализирован как класс символов соответствие символ, либо . или - (так как дефис отделался буква \) или 0. По неизвестной причине дефис анализируется как оператор диапазона, а подвыражение [a-zA-Z\\.\\-0-9]+ становится равным [a-zA-Z.-0-9]+. См. this regex demo.

Второе выражение работает, потому что - в конце символьного класса (и при его запуске) всегда анализируется как буквальный дефис.

Другой пример того же ошибка:

std::string uri = "%"; 
std::regex reg(R"([$\-&])"); 
std::smatch match; 
std::regex_match(uri, match, reg); 
for(auto& e: match) 
{ 
    std::cout<< e.str() <<std::endl; 
} 

[$\-&] регулярное выражение не должно совпадать %, он должен соответствовать $, - или &, но по какой-либо причине, % (то есть между $ и & в таблица ASCII) is still matched.

+0

Итак, что делать дальше? Где я могу зарегистрировать эту ошибку, чтобы ее устранить? – Thalhammer

+0

Вы всегда можете разместить дефис в начале или конце класса символов. –

+0

Несомненно, но эта ошибка не должна исправляться? – Thalhammer

0

Я чувствую, что это не ошибка, но я думаю, что это связано с базовой спецификацией RE.

Следует знать об особенностях литерала - (дефис), особенно, если вы хотите соответствовать такой вещи. Quoth re_format(7) (первое предложение):

Чтобы включить буквального -, сделать его первым или последним символом, или второй конечной точкой диапазона. Чтобы использовать литерал - в качестве первого конца точки диапазона, приложите его в [. и .], чтобы сделать его элементом сравнения (см. Ниже). За исключением эти и некоторые комбинации с использованием [ (см. Следующие параграфы), все остальные специальные символы, включая \, теряют свое особое значение в выражении скобки.

I.e. избегая дефиса и ожидая, что он будет соответствовать, поскольку персонаж - это точно не то, что man-страница говорит, как соответствовать буквальному дефису.

+0

Это связано с ароматом регулярного выражения POSIX, в то время как [стандартный стандартный код std :: regex ECMAScript] (http://www.cplusplus.com/reference/regex/) , Если это POSIX, регулярное выражение '' [\\] '' будет анализироваться как шаблон обратного слэша, но это [сбой] (http://coliru.stacked-crooked.com/a/adb3d3c3635dd74a). Нет такой вещи, как «базовая спецификация RE», существует много ароматизаторов регулярных выражений, а POSIX является одним из типов ароматизатора регулярных выражений. –

Смежные вопросы