在C#中搜索字符串的子字符串列表

时间:2018-02-08 14:18:58

标签: c# lambda

我有一个文件名列表:

# On branch master
# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working         directory)
#
#       deleted:    England/mana2.ttx
#       deleted:    England/test12121212.txt
#
no changes added to commit (use "git add" and/or "git commit -a")

我有一份删除候选人名单:

 List<string> FileList = new List<string>();
 FileList.Add("c:\fn1.rpt");
 FileList.Add("c:\fn2wxy.txt");
 FileList.Add("c:\fn3.pdf");

我有一个循环遍历文件名,我正在寻找正确的表达式,它基本上可以确定DeleteList中的文件名片段是否与当前文件匹配。在这种情况下,我们只会删除c:\ fn2.txt。我可以迭代列表,但似乎必须有一个超出我的智商的Lambda表达式。

非常感谢任何帮助或建议。

2 个答案:

答案 0 :(得分:3)

您不应搜索子字符串,而是使用System.IO.Path.GetFileNameWithoutExtension

例如使用LINQ(仅保留那些不会出现在DeleteList中的名称):

fileNames = fileNames
  .Where(n => !DeleteList.Contains(System.IO.Path.GetFileNameWithoutExtension(n)))
  .ToList()

如果您想忽略此案例,请将fn2FN2等同,请使用:

.Where(n => !DeleteList.Contains(System.IO.Path.GetFileNameWithoutExtension(n), StringComparer.OrdinalIgnoreCase))

答案 1 :(得分:2)

假设您在名为fileName的变量中有文件名,那么:

  • 如果您想要完全匹配,请使用Contains

if (DeleteList.Contains(fileName))

  • 如果你想要部分匹配

if (DeleteList.Any(fileToDelete => fileToDelete.Contains(fileName)))

您也可以使用ContainsStartsWith代替EndsWith

修改:我假设您的完整代码应如下所示:

foreach (filename in FileList)
{
   if (DeleteList.Any(fileToDelete => fileToDelete.Contains(fileName)))
   {
       // delete file
   }
}

尽管正如其他人所提到的那样,匹配这样的字符串并不是最好的方法。此外,创建要删除的文件列表(匹配现有文件)并将其作为最后一步进行迭代并删除文件可能更直观;像这样:

var filesToDelete = FileList.Where(f => DeleteList.Any(df => df.Contains(System.IO.Path.GetFileNameWithoutExtension(f), StringComparer.OrginalIgnoreCase)));
foreach (var filePath in filesToDelete)
{
    //delete file
}