C#匹配两个文本文件,区分大小写的问题

时间:2010-04-28 17:53:00

标签: c# string case-insensitive string-comparison

我所拥有的是两个文件,sourcecolumns.txtdestcolumns.txt。我需要做的是将源与dest进行比较,如果dest不包含源值,则将其写入新文件。下面的代码有效,除了我有这样的区分大小写的问题:

来源:CPI
dest:Cpi

因为有大写字母而不匹配,所以输出不正确。随时欢迎任何帮助!

string[] sourcelinestotal =
    File.ReadAllLines("C:\\testdirectory\\" + "sourcecolumns.txt");
string[] destlinestotal =
    File.ReadAllLines("C:\\testdirectory\\" + "destcolumns.txt");

foreach (string sline in sourcelinestotal)
{
    if (destlinestotal.Contains(sline))
    {
    }
    else
    {
        File.AppendAllText("C:\\testdirectory\\" + "missingcolumns.txt", sline);
    }
}

3 个答案:

答案 0 :(得分:5)

您可以使用IEnumerable<string>的扩展方法执行此操作,例如:

public static class EnumerableExtensions
{
    public static bool Contains( this IEnumerable<string> source, string value, StringComparison comparison )
    {
         if (source == null)
         {
             return false; // nothing is a member of the empty set
         }
         return source.Any( s => string.Equals( s, value, comparison ) );
    }
}

然后改变

if (destlinestotal.Contains( sline ))

if (destlinestotal.Contains( sline, StringComparison.OrdinalIgnoreCase ))

但是,如果这些集合很大并且/或者您经常这样做,那么您的处理方式效率非常低。基本上,您正在执行O(n 2 )操作 - 对于源中的每一行,您可以将其与目标中的所有行进行比较。最好使用case insenstivie比较器从目标列创建HashSet,然后遍历源列,检查每个列是否存在于目标列的HashSet中。这将是一个O(n)算法。请注意,HashSet上的Contains将使用您在构造函数中提供的比较器。

string[] sourcelinestotal = 
    File.ReadAllLines("C:\\testdirectory\\" + "sourcecolumns.txt"); 
HashSet<string> destlinestotal = 
                new HashSet<string>(
                  File.ReadAllLines("C:\\testdirectory\\" + "destcolumns.txt"),
                  StringComparer.OrdinalIgnoreCase
                );

foreach (string sline in sourcelinestotal) 
{ 
    if (!destlinestotal.Contains(sline)) 
    { 
        File.AppendAllText("C:\\testdirectory\\" + "missingcolumns.txt", sline); 
    } 
}

回想起来,我实际上更喜欢这个解决方案而不是简单地为IEnumerable<string>编写自己的不区分大小写的包含,除非您需要其他方法。实际上,使用HashSet实现维护的代码(您自己的代码)更少。

答案 1 :(得分:4)

为您的包含使用扩展方法。找到了一个很好的例子here on stack overflow Code不是我的,但我会在下面发布。

public static bool Contains(this string source, string toCheck, StringComparison comp) 
{
    return source.IndexOf(toCheck, comp) >= 0;
}

string title = "STRING";
bool contains = title.Contains("string", StringComparison.OrdinalIgnoreCase);

答案 2 :(得分:0)

如果您不需要区分大小写,请在比较前使用string.ToUpper将行转换为大写。