c#:不分大小写,Contains(string)

是否有方法使下面的返回为真?

1
2
string title ="ASTRINGTOTEST";
title.Contains("string");

似乎没有一个超载,使我可以设置案件敏感性..目前,我将它们都大写,但是这样做很愚蠢(我指的是i18n问题,它是由大小写组合而成的)。

更新这是一个古老的问题,从那时起,我意识到,我要求一个简单的答案,为一个非常广泛和困难的主题,如果你想要充分调查它。对于大多数情况,在单语言,英语代码的基础上,这个答案就足够了。我怀疑是因为大多数来这里的人都属于这一类这是最受欢迎的答案。然而,这个答案带来了一个固有的问题,我们不能比较文本大小写不敏感,直到我们知道两个文本是相同的文化,我们知道什么是文化。这可能是一个不太受欢迎的答案,但我认为它更正确,这就是为什么我这样标记它。


你可以用字符串。方法的索引,并传递StringComparison.OrdinalIgnoreCase作为要使用的搜索类型:

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

更好的是定义一个新的字符串扩展方法:

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


要测试字符串paragraph是否包含字符串word(谢谢@QuarterMeister)

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

其中culture是描述文本编写语言的CultureInfo的实例。

这个解决方案对于大小写不敏感的定义是透明的,大小写不敏感依赖于语言。例如,英语使用字符Ii作为第9个字母的大小写版本,而土耳其语使用这些字符作为其29个字母长的字母表的第11和第12个字母。土耳其大写字母"i"是不熟悉的字符"?"

因此,字符串tinTIN在英语中是同一个单词,但在土耳其语中是不同的单词。据我所知,一个意思是"精神",另一个是拟声词。(土耳其人,如果我错了,请纠正我,或者建议一个更好的例子)

总之,如果你知道文本的语言,你只能回答"这两个字符串是相同的,但在不同的情况下"这个问题。如果你不知道,你就得撑船。考虑到英语在软件中的霸主地位,您可能应该求助于CultureInfo.InvariantCulture,因为它会以常见的方式出错。


您可以这样使用IndexOf():

1
2
3
4
5
6
string title ="STRING";

if (title.IndexOf("string", 0, StringComparison.CurrentCultureIgnoreCase) != -1)
{
    // The string exists in the original
}

因为0(0)可以是索引,所以要检查-1。

MSDN

The zero-based index position of value if that string is found, or -1
if it is not. If value is String.Empty, the return value is 0.


使用正则表达式的替代解决方案:

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


你总是可以先让字符串上移或下移。

1
2
string title ="string":
title.ToUpper().Contains("STRING")  // returns true

哦,刚刚看到最后一点。不区分大小写的比较可能*无论如何也会执行相同的操作,如果性能不是问题,我认为创建大写副本并比较它们没有问题。我可以发誓,我曾经看到过一个不区分大小写的比较……


这个答案的一个问题是,如果字符串为空,它将抛出异常。你可以把它加到支票里,这样它就不会:

1
2
3
4
5
6
7
public static bool Contains(this string source, string toCheck, StringComparison comp)
{
    if (string.IsNullOrEmpty(toCheck) || string.IsNullOrEmpty(source))
        return true;

    return source.IndexOf(toCheck, comp) >= 0;
}


StringExtension类是前进的方向,我结合了上面的几篇文章,给出了一个完整的代码示例:

1
2
3
4
5
6
7
8
9
10
public static class StringExtensions
{
    /// <summary>
    /// Allows case insensitive checks
    /// </summary>
    public static bool Contains(this string source, string toCheck, StringComparison comp)
    {
        return source.IndexOf(toCheck, comp) >= 0;
    }
}

这是干净和简单。

1
Regex.IsMatch(file, fileNamestr, RegexOptions.IgnoreCase)


普通文化忽略酶,当前文化忽略酶还是不变文化忽略酶?

由于缺少这一功能,以下是一些关于何时使用哪一种功能的建议:

Dos

使用StringComparison.OrdinalIgnoreCase进行比较作为与区域性无关的字符串匹配的安全默认值。使用StringComparison.OrdinalIgnoreCase比较增加速度。使用StringComparison.CurrentCulture-based字符串操作当向用户显示输出时。开关电流使用基于不变式的字符串操作文化使用非语言StringComparison.OrdinalStringComparison.OrdinalIgnoreCase时的比较是语言学上不相干的(例如符号)。使用ToUpperInvariant而不是ToLowerInvariant对字符串进行规范化以便进行比较。

须知对于不显式执行的字符串操作,请使用重载或隐式指定字符串比较机制。使用基于StringComparison.InvariantCulture的字符串大多数情况下是手术;少数例外之一是坚持语言上有意义但文化上不可知的数据。

根据这些规则,你应该使用:

1
2
3
4
5
string title ="STRING";
if (title.IndexOf("string", 0, StringComparison.[YourDecision]) != -1)
{
    // The string exists in the original
}

然而[你的决定]取决于上面的建议。

资源链接:http://msdn.microsoft.com/en-us/library/ms973919.aspx


。NET Core 2.0+ only(到目前为止)

.NET Core从2.0版开始就有了两种方法来处理这个问题:

字符串。包含(Char、接受StringComparison)字符串。包含(字符串,接受StringComparison)

例子:

1
"Test".Contains("test", System.StringComparison.CurrentCultureIgnoreCase);

随着时间的推移,它们可能会进入. net标准,并从那里进入基类库的所有其他实现。


这些是最简单的解决方案。

通过索引的

1
2
3
4
5
6
string title ="STRING";

if (title.IndexOf("string", 0, StringComparison.CurrentCultureIgnoreCase) != -1)
{
    // contains
}

通过改变情况

1
2
3
string title ="STRING";

bool contains = title.ToLower().Contains("string")

通过正则表达式

1
Regex.IsMatch(title,"string", RegexOptions.IgnoreCase);


我知道这不是c#,但是在framework (VB.NET)中已经有这样一个函数

1
2
Dim str As String ="UPPERlower"
Dim b As Boolean = InStr(str,"UpperLower")

c#变体:

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


如果您关心国际化(或者您可以重新实现它),VisualBasic程序集中的InStr方法是最好的。从dotNeetPeek中可以看出,它不仅包含大写字母和小写字母,还包含假名类型和全宽与半宽的字符(主要适用于亚洲语言,尽管也有全宽的罗马字母版本)。我跳过了一些细节,但是检查一下私有方法InternalInStrText:

1
2
3
4
5
6
7
8
9
10
private static int InternalInStrText(int lStartPos, string sSrc, string sFind)
{
  int num = sSrc == null ? 0 : sSrc.Length;
  if (lStartPos > num || num == 0)
    return -1;
  if (sFind == null || sFind.Length == 0)
    return lStartPos;
  else
    return Utils.GetCultureInfo().CompareInfo.IndexOf(sSrc, sFind, lStartPos, CompareOptions.IgnoreCase | CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth);
}

就像这样:

1
2
3
4
5
string s="AbcdEf";
if(s.ToLower().Contains("def"))
{
    Console.WriteLine("yes");
}


用这个:

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


使用正则表达式是一种直接的方法:

1
Regex.IsMatch(title,"string", RegexOptions.IgnoreCase);


这与这里的其他示例非常相似,但是我决定将enum简化为bool,主要是因为通常不需要其他替代方法。下面是我的例子:

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
if("main String substring".Contains("SUBSTRING", true) )
....

这里的技巧是寻找字符串,忽略大小写,但是保持它完全相同(使用相同的大小写)。

1
2
3
4
 var s="Factory Reset";
 var txt="reset";
 int first = s.IndexOf(txt, StringComparison.InvariantCultureIgnoreCase) + txt.Length;
 var subString = s.Substring(first - txt.Length, txt.Length);

输出"重置"


1
if ("strcmpstring1".IndexOf(Convert.ToString("strcmpstring2"), StringComparison.CurrentCultureIgnoreCase) >= 0){return true;}else{return false;}


您可以使用string.indexof ()函数。这是不区分大小写的


在此基础上,你可以创建一个字符串扩展方法,让它对用户更友好:

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
public static class StringExtension
{
    #region Public Methods

    public static bool ExContains(this string fullText, string value)
    {
        return ExIndexOf(fullText, value) > -1;
    }

    public static bool ExEquals(this string text, string textToCompare)
    {
        return text.Equals(textToCompare, StringComparison.OrdinalIgnoreCase);
    }

    public static bool ExHasAllEquals(this string text, params string[] textArgs)
    {
        for (int index = 0; index < textArgs.Length; index++)
            if (ExEquals(text, textArgs[index]) == false) return false;
        return true;
    }

    public static bool ExHasEquals(this string text, params string[] textArgs)
    {
        for (int index = 0; index < textArgs.Length; index++)
            if (ExEquals(text, textArgs[index])) return true;
        return false;
    }

    public static bool ExHasNoEquals(this string text, params string[] textArgs)
    {
        return ExHasEquals(text, textArgs) == false;
    }

    public static bool ExHasNotAllEquals(this string text, params string[] textArgs)
    {
        for (int index = 0; index < textArgs.Length; index++)
            if (ExEquals(text, textArgs[index])) return false;
        return true;
    }

    /// <summary>
    /// Reports the zero-based index of the first occurrence of the specified string
    /// in the current System.String object using StringComparison.InvariantCultureIgnoreCase.
    /// A parameter specifies the type of search to use for the specified string.
    /// </summary>
    /// <param name="fullText">
    /// The string to search inside.
    /// </param>
    /// <param name="value">
    /// The string to seek.
    /// </param>
    /// <returns>
    /// The index position of the value parameter if that string is found, or -1 if it
    /// is not. If value is System.String.Empty, the return value is 0.
    /// </returns>
    /// <exception cref="ArgumentNullException">
    /// fullText or value is null.
    /// </exception>
    public static int ExIndexOf(this string fullText, string value)
    {
        return fullText.IndexOf(value, StringComparison.OrdinalIgnoreCase);
    }

    public static bool ExNotEquals(this string text, string textToCompare)
    {
        return ExEquals(text, textToCompare) == false;
    }

    #endregion Public Methods
}

如果你想检查你传递的字符串是否在字符串中,有一个简单的方法。

1
2
3
4
5
6
string yourStringForCheck="abc";
string stringInWhichWeCheck="Test abc abc";

bool isContaines = stringInWhichWeCheck.ToLower().IndexOf(yourStringForCheck.ToLower()) > -1;

This boolean value will return if string contains or not

新手的简单方法:

1
title.ToLower().Contains("string");//of course"string" is lowercase.