【问题标题】:How to search a path for files with a specific patern如何在路径中搜索具有特定模式的文件
【发布时间】:2013-12-23 18:07:06
【问题描述】:

如果文件与模式匹配,我正在寻找一种在目录(及其子目录)中查找文件的方法。

我有这个代码:

 inline static void ScanForFiles(std::vector<string> &files,const path &inputPath,string filter="*.*",bool recursive=false)
 {
        typedef vector<boost::filesystem::path> vec;             // store paths,
        vec v;                                // so we can sort them later

        copy(directory_iterator(inputPath), directory_iterator(), back_inserter(v));
        for(int i=0; i<v.size(); i++)
        {
            if(IsDirectory(v[i]))
            {
                if(recursive)
                {
                    ScanForDirs(files,v[i],recursive);
                }
            }
            else
            {
                if(File::IsFile(v[i]))
                {
                    files.push_back(v[i].string());
                }
            }
        }
}

这是有效的,但它与模式不匹配。例如我想这样调用这个函数:

std::vector<string> files;
ScanForFiles(files,"c:\\myImages","*.jpg",true);

我得到了 myimages 及其所有子文件夹中所有 jpeg 图像的列表。

当前代码返回所有图像且没有模式匹配。

如何更改上述代码?

【问题讨论】:

  • 这看起来像 stackoverflow.com/questions/1257721/… 的副本
  • @ales_t:问题是将过滤器从“*.jpg”的普通类型转换为正则表达式格式。诸如此类的东西是 regex filter("*.jpg") 不起作用。我需要让这个函数的用户以不好的正则表达式格式编写过滤器,或者转换它似乎我不能。有什么解决办法吗?
  • 您可以尝试编写一个将通配符转换为正则表达式的函数。只要你只支持*?,你就可以转义模式,然后将\*替换为.*,将\?替换为.?,见这里:codeproject.com/Articles/11556/Converting-Wildcards-to-Regexes
  • 另一方面,例如bash 通配符要丰富得多,编写一个处理其所有功能的转换函数可能会很棘手。
  • @ales_t: ( ) { } 等呢,我觉得也应该转换一下。

标签: c++ boost filesystems


【解决方案1】:

我想出了以下sn-p:

#include <iostream>
#include <string>
#include <boost/regex.hpp>

std::string escapeRegex(const std::string &str) {
  boost::regex esc("([\\^\\.\\$\\|\\(\\)\\[\\]\\*\\+\\?\\/\\\\])");                                                         
  std::string rep("\\\\\\1");
  return regex_replace(str, esc, rep, boost::match_default | boost::format_sed);
}

std::string wildcardToRegex(const std::string &pattern) {
  boost::regex esc("\\\\([\\*\\?])");
  std::string rep(".\\1");
  return regex_replace(escapeRegex(pattern), esc, rep, boost::match_default | boost::format_sed);
}

using namespace std;
using namespace boost;
int main(int argc, char **argv) {
  string pattern = "test/of regexes/*.jpg";
  cout << wildcardToRegex(pattern) << endl;
}

它很大程度上基于this question。我希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-01
    • 2020-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-08
    • 1970-01-01
    相关资源
    最近更新 更多