如何进行不区分大小写的字符串比较?

Posted

技术标签:

【中文标题】如何进行不区分大小写的字符串比较?【英文标题】:How can I do a case insensitive string comparison? 【发布时间】:2011-03-08 12:13:09 【问题描述】:

如何使下面的行不区分大小写?

drUser["Enrolled"] = 
      (enrolledUsers.FindIndex(x => x.Username == (string)drUser["Username"]) != -1);

今天早些时候有人给了我一些建议,建议我使用:

x.Username.Equals((string)drUser["Username"], StringComparison.OrdinalIgnoreCase)));

问题是我无法让它工作,我尝试了下面的行,它编译但返回错误的结果,它将注册用户返回为未注册和未注册用户注册。

drUser["Enrolled"] = 
      (enrolledUsers.FindIndex(x => x.Username.Equals((string)drUser["Username"], 
                                 StringComparison.OrdinalIgnoreCase)));

谁能指出问题所在?

【问题讨论】:

drUser["Enrolled"] 应该是什么数据类型?它看起来像一个布尔值,但 FindIndex() 返回索引。如果该用户的索引为 0,那么它将返回 0,这可能是错误的。当,在现实中是真的。在这种情况下,Exists() 方法可能会更好。 您确定在一个字段中没有格式化时间或在另一个字段中没有多余的空格吗? 我建议使用 registeredUsers.Any() 而不是 FindIndex (和测试)。 【参考方案1】:

这不是 .NET 框架(4 & +)中检查相等性的最佳实践

String.Compare(x.Username, (string)drUser["Username"], 
                  StringComparison.OrdinalIgnoreCase) == 0

改用下面的

String.Equals(x.Username, (string)drUser["Username"], 
                   StringComparison.OrdinalIgnoreCase) 

MSDN recommends:

使用 String.Equals 方法的重载来测试两个字符串是否相等。 使用 String.CompareString.CompareTo 方法对字符串进行排序,不检查相等性

【讨论】:

你应该使用string.Compare,而不是String.Compare @Fred 我同意,但你能说明原因吗? @Fred 我希望是出于技术原因,而不是“因为 Stylecop 这么说”。我错过了什么吗? string.compare 与 String.Compare 没有区别,字符串同义词 System.String 类。并且成员 Compare 是一个扩展方法。@Fred @Gusdor @Gusdor stringString 更好,因为它是一个语言关键字。一方面,String 可能不是System.String,而string 不能。此外,string 或多或少保证存在于 C# 中,而 String 在技术上属于 .NET 而不是 C#。【参考方案2】:

您应该使用静态String.Compare 函数,如下所示

x => String.Compare (x.Username, (string)drUser["Username"],
                     StringComparison.OrdinalIgnoreCase) == 0

【讨论】:

不,您应该使用String.Equals 而不是String.Compare。不需要计算哪个更大,只是它们不相等。 @ErikE:我想知道,你会在 6 年后推荐使用哪种方法 :-) 我不奇怪!我相信我会建议您在需要相等语义时使用相等,并在需要比较语义时使用 compare。这有什么难的? IEquatableIComparable 不会做同样的事情,您可以拥有实现一个但在其中实现另一个没有意义的类。例如,您可以按时间排序传感器采样,而其中任何一个都不相等(IComparable)。而且,您可以指示事物是否相等 (IEquatable),但对它们进行排序是没有意义的(例如,计算机序列号)。 @ErikE:你不理解我的观点。旧答案对应于写作时间。不应该触及旧的答案。大多数产品都是如此。从性能的角度来看,最佳实践或最佳选择可以在以后多次更改。我认为讨论任何旧答案毫无意义。 抱歉,我认为这是对我评论正确性的批评。如果您要说的是您承认您的旧答案可能不是最好的答案,那就太好了!但是,对于旧的答案,我不得不不同意你的看法。提供不良信息的旧答案应该被评论,应该被否决,因为它们仍在通知今天的读者。【参考方案3】:

请用这个来比较:

string.Equals(a, b, StringComparison.CurrentCultureIgnoreCase);

【讨论】:

请注意使用 CurrentCultureIgnoreCase 与 OrdinalIgnoreCase 的优缺点。如果你不需要文化比较的语义,节省一些性能并使用序数比较。【参考方案4】:

其他答案在这里完全有效,但不知何故,输入StringComparison.OrdinalIgnoreCase 并使用String.Compare 需要一些时间。

我编写了简单的字符串扩展方法,您可以在其中指定比较是否区分大小写或不区分大小写与布尔值,在此处附加整个代码 sn-p:

using System;

/// <summary>
/// String helpers.
/// </summary>
public static class StringExtensions

    /// <summary>
    /// Compares two strings, set ignoreCase to true to ignore case comparison ('A' == 'a')
    /// </summary>
    public static bool CompareTo(this string strA, string strB, bool ignoreCase)
    
        return String.Compare(strA, strB, ignoreCase) == 0;
    

在整个比较之后大约缩短了 10 个字符 - 比较:

使用字符串扩展之前:

String.Compare(testFilename, testToStart,true) != 0

使用字符串扩展后:

testFilename.CompareTo(testToStart, true)

【讨论】:

我不同意这个命名,比较是软件开发中众所周知的功能,而您已经从根本上改变了它的作用。我认为您应该返回一个类似 compare 的 int 或将名称更改为其他名称,例如“IsEqual”。【参考方案5】:

您可以(尽管有争议)扩展 System.String 以提供不区分大小写的比较扩展方法:

public static bool CIEquals(this String a, String b) 
    return a.Equals(b, StringComparison.CurrentCultureIgnoreCase);

并像这样使用:

x.Username.CIEquals((string)drUser["Username"]);

C# 允许您创建可以在项目中用作语法糖的扩展方法,我会说非常有用。

这不是答案,我知道这个问题已经过时且已解决,我只是想添加这些位。

【讨论】:

【参考方案6】:

我想你会在这个链接中找到更多信息:

http://codeidol.com/community/dotnet/controlling-case-sensitivity-when-comparing-two-st/8873/

使用 String 类的 Compare 静态方法来比较两个字符串。比较是否不区分大小写由其重载之一的第三个参数确定。例如:

string lowerCase = "abc";
string upperCase = "AbC";
int caseInsensitiveResult = string.Compare(lowerCase, upperCase,
  StringComparison.CurrentCultureIgnoreCase);
int caseSensitiveResult = string.Compare(lowerCase,
  StringComparison.CurrentCulture);

caseSensitiveResult 值为 -1(表示 lowerCase“小于”upperCase),caseInsensitiveResult 为零(表示 lowerCase“等于”upperCase)。

【讨论】:

【参考方案7】:

我想为 EqualsIgnoreCase 写一个扩展方法

public static class StringExtensions

    public static bool? EqualsIgnoreCase(this string strA, string strB)
    
        return strA?.Equals(strB, StringComparison.CurrentCultureIgnoreCase);
    

【讨论】:

【参考方案8】:

改用StringComparison.CurrentCultureIgnoreCase怎么样?

【讨论】:

-1:这个答案是不够的。请看@ocean4dream 的回答:***.com/a/13965429/109941。 @decyclone:它比 OrdinalIgnoreCase 慢,但在某些情况下可能相关。因此我不会给-1。 ***.com/questions/2749662/… 还有***.com/questions/72696/…【参考方案9】:

你总是可以使用函数: 。降低(); .ToUpper();

转换您的字符串,然后比较它们...

祝你好运

【讨论】:

我认为这不会解决他的问题。还要标记这个问题已经超过 4 年了。 这会创建一个新字符串,所以我认为这非常低效。因为要创建这个新字符串,所有字符都将被检查并转换为所需的大小写,因此比较必须再次检查所有字符。所以它使用更多的内存和处理能力。 由于内存分配,这是非常糟糕的做法。 这不仅是不必要的内存分配,而且效率低下;它也使Turkey test 失败。

以上是关于如何进行不区分大小写的字符串比较?的主要内容,如果未能解决你的问题,请参考以下文章

如何对区分大小写的字符串进行比较

字符串的字典比较[不区分大小写]

Django模板中的Django不区分大小写字符串比较

字符串比较时如何将Sqlite3设置为不区分大小写?

mysql模糊查询区分大小写

与一堆字符串比较不区分大小写