使用正则表达式搜索文件

本文关键字:文件 搜索 正则表达式 | 更新日期: 2023-09-27 18:07:22

我有以下递归搜索函数:

public List<FileInfo> Search_Files(String strDir, String line)
{
    List<FileInfo> files = new List<FileInfo>();
    try
    {
         foreach (String strFile in Directory.GetFiles(strDir,line+r))
         {
             files.Add(new FileInfo(strFile));
         }
         foreach (String strSubDir in Directory.GetDirectories(strDir))
         {
             List<FileInfo> sublist = Search_Files(strSubDir, line);
             foreach (FileInfo file_infow in sublist)
             {
                 files.Add(file_infow);
             }
         }
    }
    catch (Exception)
    {
         ...
    }
    return (files);
}

line变量的值看起来像"1234"。现在我想搜索像:1234c这样的文件。Something or 1234.something

我创建了以下Regex:

Regex r = new Regex("[a-z].* | .*");

我将它添加到行字符串中,但它不起作用。为什么这不能工作,我如何纠正这一点?

使用正则表达式搜索文件

我用的是LINQ,试一试

string[] allFiles =  Directory.GetFiles(@"C:'Users'UserName'Desktop'Files");
List<string> neededFiles = (from c in allFiles
                               where Path.GetFileName(c).StartsWith("fileStartName")
                               select c).ToList<string>();
foreach (var file in neededFiles)
{
   // do the tesk you want with the matching files
}

GetDirectoriesGetFiles方法接受searchPattern,该不是正则表达式。

要与path中的文件名匹配的搜索字符串。该参数可以包含有效的文字路径和通配符(*?)字符的组合(参见备注),但不支持正则表达式。

您可以使用以下正则表达式过滤结果:

var r = new Regex(@"'d{4}.*");
// var r = new Regex(@"^'d{4}.*"); // Use this if file names should start with the 4 digits.
files.Add(Directory.GetFiles(strDir)
            .Where(p => r.IsMatch(Path.GetFileName(p)))
            .ToList());

'd{4}.*正则表达式匹配4位数字('d{4})和除换行符以外的任何0或更多字符。

如果你想匹配'。你必须将其转义为''.'。'.*'本身表示任意字符n次。有关格式的详细信息请查看此处:https://msdn.microsoft.com/en-us/library/az24scfc(v=vs.110).aspx

我还建议您使用更严格的正则表达式。如果您知道文件名以1234开头,那么也可以在正则表达式中使用它。

有两种方法可以做到这一点。第一种方法是使用windows搜索过滤器。这是您可以直接传递给GetFiles()方法的内容。(EnumerateFiles()做同样的事情,在这种情况下可能更快,但这与你的问题无关)。

windows搜索模式使用*来表示'任意数量的任意字符',而?用于表示单个未知字符。这些实际上不是正则表达式。

您可以执行如下搜索:

return Directory.EnumerateFiles(strDir, line + "*.*", SearchOption.AllDirectories)
                .Select(f => new FileInfo(f))
                .ToList();

第二个是你最初寻找的,它使用实际的正则表达式执行linq查询。可以这样做:

Regex pattern = new Regex(line + @".*'..*") 
// regex says use line, then anything any number of times, 
// and then a dot and then any chars any amount of times
return Directory.EnumerateFiles(strDir, *.*, SearchOption.AllDirectories)
                .Where(f => pattern.IsMatch(f))
                .Select(f => new FileInfo(f))
                .ToList();

注意:上面的两个例子展示了如何将提供的字符串转换为FileInfo对象,就像你的Search_Files方法在"linq-way"中要求的签名一样。此外,我使用SearchOption.AllDirectories标志,为您执行递归搜索,而无需您自己编写。

至于为什么你原来发布的方法不工作;这里有两个问题。

  1. 你正在尝试连接一个正则表达式对象和一个字符串。这是不可能的,因为您正在寻找将正则表达式模式与字符串连接起来。这应该在我的示例中所示的regex对象的构造之前(或内部)完成。

  2. 假设您没有尝试将regex对象与字符串连接起来,那么您使用的regex模式几乎总是可以匹配任何内容。