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

Что я знаю об именах файлов, которые я пытаюсь извлечь, так это то, что им предшествует упоминание 'file =', имя файла заключено в кавычки между '' или "". Пример: file = "name.abc". У меня также нет гарантии, какой у меня интервал: это может быть file = "name.abc", file = "name.abc", file = "name.abc" ... И расширение может быть разной длины.

Итак, я попробовал следующий код:

std::vector<std::string> attachment_names;
std::istringstream words(text_content);
std::string word;
std::string pst_extension(".abc"); // My code should support any extension
while (words >> word)
{
    auto extension_found = word.find(abc_extension);
    if (extension_found != word.npos)
    {
        auto name_start = word.find("'") + 1; 
             //I am not even sure the file is quoted by ''

        std::string attachment_name = word.substr(name_start, (extension_found + 3) - name_start + 1); 
             //Doing this annoys me a bit... Especially that the extension may be longer than 3 characters

        attachment_names.push_back(attachment_name);
    }
}

Есть ли способ сделать это лучше? Есть ли возможность больше полагаться на заголовок файла для поддержки любого расширения?

1
hamza keurti 15 Ноя 2017 в 20:00

1 ответ

Лучший ответ

С C ++ 11 или с помощью Boost я рекомендую вам используйте регулярное выражение с итератором регулярных выражений для этой проблемы, так как у вас есть различия в количестве пробелов, и синтаксический анализ будет немного беспорядочным. Sregex_iterator будет проходить по тексту и сопоставлять регулярные выражения (вы можете использовать в качестве источника любой двунаправленный итератор, например, строки, взятые с getline). Далее следует непроверенная идея:

static std::regex const filename_re("[[:space:]]*file[[:space:]]*=(.*)[[:space:]]*");

std::regex_iterator rit(line.begin(), line.end(), filename_re), end;


while (rit != end) {
  cout << rit[1] << ',';
  ++rit;
}

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

1
Germán Diago 15 Ноя 2017 в 17:25