使用正则表达式搜索文件
本文关键字:文件 搜索 正则表达式 | 更新日期: 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
}
GetDirectories
和GetFiles
方法接受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
标志,为您执行递归搜索,而无需您自己编写。
至于为什么你原来发布的方法不工作;这里有两个问题。
你正在尝试连接一个正则表达式对象和一个字符串。这是不可能的,因为您正在寻找将正则表达式模式与字符串连接起来。这应该在我的示例中所示的regex对象的构造之前(或内部)完成。
假设您没有尝试将regex对象与字符串连接起来,那么您使用的regex模式几乎总是可以匹配任何内容。