Check String包含列表中使用Linq且不区分大小写的所有元素
本文关键字:大小写 不区 元素 Linq 包含 String 列表 Check | 更新日期: 2023-09-27 18:22:17
我想写一个函数来过滤目录中的文件。方法接收的路径、文件必须包含的令牌列表以及不应在文件中的令牌列表。
我的代码是这样的:
private String[] enumerateFilesByFilter(String path, List<String> contain, List<String> notContain)
{
String[] files = Directory.GetFiles(path).Where(f => (contain.All(f.Contains)) && (!notContain.Any(f.Contains))).ToArray();
//String[] files = Directory.GetFiles(path).Where(f => f.IndexOf(contain.All(f.Contains), 0, StringComparison.CurrentCultureIgnoreCase) != -1).ToArray();
return files;
}
我尝试接收符合条件的文件列表,并成功获得正确的列表,但仅针对敏感令牌。
(在推荐中,你可以看到我试图获得一个不区分大小写的,但有一个错误…)
如何检查文件名是否包含列表中不区分大小写的所有字符串?
编辑
下面是一个例子。假设我的目录中有以下文件:
proj_debug_3.20.txt
proj_release_3.2.1.txt
proj_release_3.2.1_useThis_TRY.txt
proj_release_3.2.1_UseThis.txt
所以呼叫
enumerateFilesByFilter(path, new List<String> { "Release", "useThis" }, new List<String> {"try", "debug" });
应返回proj_release_3.2.1_UseThis.txt
文件
首先,我为不区分大小写的搜索定义了一种新的扩展方法:
public static class StringExtensions
{
public static bool Contains(this string source, string pattern, StringComparison comparision)
{
return source.IndexOf(pattern, comparision) >= 0;
}
}
然后像这样重写你的方法:
public static IEnumerable<string> EnumerateFilesByFilter(String path, List<String> include, List<String> exclude)
{
return Directory.EnumerateFiles(path).
Where(f => include.All(i => f.Contains(i, StringComparison.OrdinalIgnoreCase))).
Where(f => exclude.All(i => !f.Contains(i, StringComparison.OrdinalIgnoreCase)));
}
请注意,我使用IEnumerable作为返回类型,使用Directory.EnumerateFiles()作为文件系统列表。通过这种方式,整个操作更加高效,并且只使用可枚举项。
这应该可以根据需要工作:
private String[] enumerateFilesByFilter(String path, List<String> contain, List<String> notContain)
{
String[] files = Directory.EnumerateFiles(path)
.Where(f => contain.All(s => s.IndexOf(f, StringComparison.CurrentCultureIgnoreCase) >= 0)
&& !notContain.Any(s => s.IndexOf(f, StringComparison.CurrentCultureIgnoreCase) >= 0))
.ToArray();
return files;
}
注意,我使用Directory.EnumerateFiles
而不是Directory.GetFiles
,因为它可以在返回所有文件之前开始处理,而GetFiles
首先创建所有文件的数组。
也许您还应该考虑使用System.IO.Path.GetFileName(f)
只检查文件名,而不是完整路径。
最后我找到了解决方案(解决方案很难看,但有效):
private String[] enumerateFilesByFilter(String path, List<String> contain, List<String> notContain)
{
String[] files = Directory.EnumerateFiles(path).Where(f => (contain.All(c => f.ToLower().Contains(c.ToLower()))) &&
(!notContain.Any(c => f.ToLower().Contains(c.ToLower())) )).ToArray();
return files;
}