2016-01-20 3 views
1

я планировал использовать следующее регулярное выражение, чтобы захватить путь и имя файла:регулярного выражения Visual Studio

std::regex capture_path_name_file("(.+)\\([^\\]+)\\.[^\\]+$"); 

но при запуске (я использую Visual Studio) я получаю ошибку REGEX

error_brack: the expression contained mismatched [ and ] 

Пытаясь определить причину я попробовал следующее регулярное выражение:

std::regex test("[^\\]") 

и я получил ту же ошибку.

Я проверил мое регулярное выражение в regex101.com (с небольшой разницей, что я должен был использовать \. вместо \\.)

Спасибо за любую помощь.

+2

В синтаксисе C++ '' [^ \\] "' означает '[^ \]', который в регулярном выражении является несогласованным '['. Если вы хотите создать класс символов «не обратная косая черта», вам придется сбежать один раз для C++ и один раз для регулярного выражения, т. Е. '[^ \\\\]'. – Biffen

+0

Это для php, но также должно ответить на ваш вопрос: http://stackoverflow.com/a/14783396/4181011 –

+1

См. [Это демо] (https://ideone.com/UpArVo). –

ответ

1

Вопрос у вас есть, потому что \\ рассматривается как 1 буквальный \ символ в правильных строковых литералах. Biffen объяснил это хорошо в his comment, [^\\] трактуются как [^\], то ] трактуются как буквальный ] и не закрывающий класс символов разделителя (и не существует соответствие ], чтобы закрыть класс символов далее).

Правильный ответ: использовать _splitpath_s.

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

#include <iostream> 
#include <regex> 
using namespace std; 

int main() { 
    std::regex rex1(R"((.+?)([^\\.]+\.[^\\.]+)$)"); 
    std::smatch m; 
    std::string str = "c:\\Python27\\REGEX\\test_regex.py"; 
    if (regex_search(str, m, rex1)) { 
     std::cout << "Path: " << m[1] << std::endl; 
     std::cout << "File name: " << m[2] << std::endl; 
    } 
    return 0; 
} 

Использования сырья строковых литералов, вы можете избежать большинства проблем, связанные с побегом. Используйте R"((.+?)([^\\.]+\.[^\\.]+)$)", он будет сопоставлять и записывать в папку 1 путь к папке файла, и он будет захватывать в группу 2 имя файла с расширением. Обратите внимание, что расширение должно присутствовать.

+0

Я бы решительно утверждал, что '_splitpath_s' является _not_ хорошим решением, а скорее для итерации через экземпляр [' std :: tr2 :: path'] (https://msdn.microsoft.com/en-us/library /hh874769%28v=vs.120%29.aspx) ('std :: experimental :: path' в VC++ 2015). – ildjarn

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