使用 Linq 和不区分大小写检查字符串是否包含列表中的所有元素

Check String contain all elements in list using Linq and case insensitive

我想写一个函数来过滤目录中的文件。方法接收路径、文件必须包含的标记列表以及不应包含在文件中的标记列表。

我的代码是这样的:

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.2.0.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" });

应该returnproj_release_3.2.1_UseThis.txt文件

谢谢!

这应该可以正常工作:

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) 来仅检查文件名而不是完整路径。

首先,我会为不区分大小写的搜索定义一个新的扩展方法:

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 作为 return 类型,并使用 Directory.EnumerateFiles() 作为文件系统列表。这样整个操作效率更高,并且只使用枚举。

最后我找到了解决方案(这个解决方案很丑但有效):

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;
}