Case insensitive 'Contains(string)'

Case insensitive ‘Contains(string)’

技术背景

在软件开发中,经常需要判断一个字符串是否包含另一个字符串,并且有时需要忽略大小写进行匹配。例如,在搜索功能中,用户输入的关键词可能大小写与目标字符串不一致,但我们仍希望能正确匹配。

实现步骤

1. 使用 String.IndexOf 方法

可以使用 String.IndexOf 方法并传入 StringComparison.OrdinalIgnoreCase 作为搜索类型:

1
2
string title = "STRING";
bool contains = title.IndexOf("string", StringComparison.OrdinalIgnoreCase) >= 0;

2. 定义扩展方法

为字符串定义一个新的扩展方法:

1
2
3
4
5
6
7
public static class StringExtensions
{
public static bool Contains(this string source, string toCheck, StringComparison comp)
{
return source?.IndexOf(toCheck, comp) >= 0;
}
}

注意,?. 是 C# 6.0(VS 2015)引入的空传播运算符,对于旧版本可以使用:

1
2
if (source == null) return false;
return source.IndexOf(toCheck, comp) >= 0;

使用示例:

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

3. 使用 CultureInfo.CompareInfo.IndexOf

要测试字符串 paragraph 是否包含字符串 word,可以使用:

1
culture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0

其中 cultureCultureInfo 的实例,描述文本所使用的语言。

4. .NET Core 2.0+

.NET Core 2.0 及以上版本提供了两个方法来处理此问题:

  • String.Contains(Char, StringComparison)
  • String.Contains(String, StringComparison)
    示例:
1
"Test".Contains("test", System.StringComparison.CurrentCultureIgnoreCase);

5. 使用正则表达式

1
bool contains = Regex.IsMatch("StRiNG to search", Regex.Escape("string"), RegexOptions.IgnoreCase);

6. 先转换大小写

1
2
string title = "string";
title.ToUpper().Contains("STRING");

7. 使用 InStr 方法

在 VB.NET 中已经有这样的函数,C# 可以使用 Microsoft.VisualBasic.Strings.InStr 方法:

1
2
string myString = "Hello World";
bool contains = Microsoft.VisualBasic.Strings.InStr(myString, "world");

8. 使用 string.Compare 方法

1
string.Compare("string", "STRING", new System.Globalization.CultureInfo("en-US"), System.Globalization.CompareOptions.IgnoreCase);

9. 自定义扩展方法

1
2
3
4
public static bool ContainsIgnoreCase(this string paragraph, string word)
{
return CultureInfo.CurrentCulture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0;
}

10. 简化扩展方法

1
2
3
4
5
6
7
public static class StringExtensions
{
public static bool Contains(this string source, string toCheck, bool bCaseInsensitive )
{
return source.IndexOf(toCheck, bCaseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal) >= 0;
}
}

使用示例:

1
2
3
4
if( "main String substring".Contains("SUBSTRING", true) )
{
// 包含
}

11. 简单的检查方法

1
2
3
string yourStringForCheck = "abc";
string stringInWhichWeCheck = "Test abc abc";
bool isContained = stringInWhichWeCheck.ToLower().IndexOf(yourStringForCheck.ToLower()) > -1;

12. 带空检查的扩展方法

1
2
3
4
public static bool ContainsIgnoreCase(this string source, string substring)
{
return source?.IndexOf(substring ?? "", StringComparison.OrdinalIgnoreCase) >= 0;
}

最佳实践

  • 对于不涉及特定文化的字符串匹配,建议使用 StringComparison.OrdinalIgnoreCase 作为默认选项,因为它速度更快。
  • 当需要向用户显示输出时,使用基于 StringComparison.CurrentCulture 的字符串操作。
  • 在比较与语言无关的符号时,将当前基于不变文化的字符串操作切换为使用非语言的 StringComparison.OrdinalStringComparison.OrdinalIgnoreCase
  • 规范化字符串进行比较时,使用 ToUpperInvariant 而不是 ToLowerInvariant

常见问题

  • 空字符串问题:如果字符串为 null,某些方法可能会抛出异常。可以在方法中添加空检查来避免这种情况,如在扩展方法中添加 if (string.IsNullOrEmpty(toCheck) || string.IsNullOrEmpty(source)) return true;
  • 文化差异问题:不同语言对大小写的定义可能不同,如英语和土耳其语。在进行大小写不敏感比较时,需要考虑文本所使用的语言。如果不知道语言,可以使用 CultureInfo.InvariantCulture

Case insensitive 'Contains(string)'
https://119291.xyz/posts/2025-05-09.case-insensitive-contains-string/
作者
ww
发布于
2025年5月9日
许可协议