提问



有没有办法让以下返回true?


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


似乎没有一个过载允许我设置区分大小写。目前我大写它们两个,但这只是愚蠢(我指的是上下套管带来的i18n问题) [63]


更新结果
这个问题很古老,从那时起我就意识到,如果你想彻底调查它,我会要求一个简单的答案来解决一个非常庞大而困难的话题。

对于大多数情况,在单语言的英语代码库中,这个答案就足够了。我怀疑是因为大多数人来到这个类别这是最受欢迎的答案
然而,这个答案提出了一个固有的问题,我们不能比较文本不区分大小写,直到我们知道两个文本是相同的文化,我们知道这种文化是什么。这可能是一个不太受欢迎的答案,但我认为它更正确,这就是为什么我这样做的标记。

最佳参考


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


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


其中culture是描述文本所用语言的CultureInfo的实例。[66]


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


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


总而言之,如果您知道文本在中的语言,那么您只能回答这两个字符串是否相同但在不同情况下的问题。如果你不知道,你将不得不采取行动。鉴于英语在软件方面的霸权,你应该诉诸CultureInfo.InvariantCulture,因为它会以熟悉的方式出错。

其它参考1


你可以使用String.IndexOf方法并传递StringComparison.OrdinalIgnoreCase作为要使用的搜索类型:[69] [70]


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


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


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)起,空传播?.可用,旧版本使用


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


用法:


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

其它参考2


您可以像这样使用IndexOf():


string title = "STRING";

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


由于0(零)可以是索引,因此请检查-1。


MSDN [72]



  如果找到该字符串,则从零开始的索引位置值为-1
  如果不是。如果value为String.Empty,则返回值为0。


其它参考3


使用Regex的替代解决方案:


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


通知


正如@cHao在他的评论中指出的那样,有一些情况会导致这个解决方案返回不正确的结果。确保在随意实施此解决方案之前知道自己在做什么。

其它参考4


您可以先将字符串向上或向下翻转。


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


哎呀,刚看到最后一点。一个不区分大小写的比较会*可能*做同样的事情,如果性能不是问题,我不会发现创建大写副本和比较那些问题。我可以发誓说我曾经看过一次不区分大小写的比较...

其它参考5


答案的一个问题是,如果字符串为null,它将抛出异常。您可以将其添加为支票,以便赢得t:


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

其它参考6


StringExtension类是前进的方法,我已经结合了上面的几个帖子来给出一个完整的代码示例:


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

其它参考7


这很干净简单


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

其它参考8


OrdinalIgnoreCase,CurrentCultureIgnoreCase还是InvariantCultureIgnoreCase?


由于缺少这个,这里有一些关于何时使用哪一个的建议:


待办事项




  • 使用StringComparison.OrdinalIgnoreCase进行比较
    作为与文化无关的字符串匹配的安全默认值。

  • 使用StringComparison.OrdinalIgnoreCase比较
    提高速度。

  • 使用StringComparison.CurrentCulture-based字符串操作
    在向用户显示输出时。

  • 根据不变量切换当前字符串操作的使用
    当比较为
    时,文化使用非语言StringComparison.OrdinalStringComparison.OrdinalIgnoreCase
    在语言上无关紧要(例如,象征性的)。

  • 使用ToUpperInvariant而不是ToLowerInvariant
    规范化字符串以进行比较。



唐TS




  • 对不明确的字符串操作使用重载
    或隐式指定字符串比较机制。

  • 使用基于StringComparison.InvariantCulture的字符串

    大多数情况下的操作;少数例外之一将是

    坚持语言上有意义但与文化无关的数据。






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


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


而[[YourDecision]]取决于上述建议。


来源链接:http://msdn.microsoft.com/en-us/library/ms973919.aspx [73]

其它参考9


像这样:


string s="AbcdEf";
if(s.ToLower().Contains("def"))
{
    Console.WriteLine("yes");
}

其它参考10


如果您对国际化有所顾虑(或者您可以重新实现),那么VisualBasic程序集中的InStr方法是最好的。在它看来dotNeetPeek显示它不仅占大写字母和小写字母,而且还包括假名类型和全长与半宽字符(主要与亚洲语言相关,尽管罗马字母也有全宽版本) )。我正在跳过一些细节,但查看私有方法InternalInStrText:


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

其它参考11


我知道这不是C#,但在框架(VB.NET)中已经存在这样的功能


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


C#变种:


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

其它参考12


用这个:


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

其它参考13


最终,通用的包含操作归结为这样的函数,


/// <summary>
/// Determines whether the source contains the sequence.
/// </summary>
/// <typeparam name="T">The type of the items in the sequences.</typeparam>
/// <param name="sourceEnumerator">The source enumerator.</param>
/// <param name="sequenceEnumerator">The sequence enumerator.</param>
/// <param name="equalityComparer">An equality comparer.</param>
/// <remarks>
/// An empty sequence will return <c>true</c>.
/// The sequence must support <see cref="IEnumerator.Reset"/>
/// if it does not begin the source.
/// </remarks>
/// <returns>
/// <c>true</c> if the source contains the sequence;
/// otherwise <c>false</c>.
/// </returns>
public static bool Contains<T>(
    IEnumerator<T> sourceEnumerator,
    IEnumerator<T> sequenceEnumerator,
    IEqualityComparer<T> equalityComparer)
{
    if (equalityComparer == null)
    {
        equalityComparer = EqualityComparer<T>.Default;
    }

    while (sequenceEnumerator.MoveNext())
    {
        if (sourceEnumerator.MoveNext())
        {
            if (!equalityComparer.Equals(
                sourceEnumerator.Current,
                sequenceEnumerator.Current))
            {
                sequenceEnumerator.Reset();
            }
        }
        else
        {
            return false;
        }
    }

    return true;
}


这可以简单地包含在接受IEnumerable这样的扩展版本中,


public static bool Contains<T>(
        this IEnumerable<T> source,
        IEnumerable<T> sequence,
        IEqualityComparer<T> equalityComparer = null)
{
    if (sequence == null)
    {
        throw new ArgumentNullException("sequence");
    }

    using(var sequenceEnumerator = sequence.GetEnumerator())
    using(var sourceEnumerator = source.GetEnumerator())
    {
        return Contains(
            sourceEnumerator,
            sequenceEnumerator,
            equalityComparer);
    }
}


现在,这将适用于任何序列的序数比较,包括字符串,因为string实现IEnumerable<char>


// The optional parameter ensures the generic overload is invoked
// not the string.Contains() implementation.
"testable".Contains("est", EqualityComparer<char>.Default)


但是,正如我们所知,字符串不是通用的,它们是专门的。有两个关键因素在起作用。



  1. 套管问题本身有各种与语言相关的边缘情况。

  2. 关于如何用Unicode代码点表示一组文本元素(字母/数字/符号等)以及字符的有效序列可以表示给定字符串的相关问题,详细信息在这些答案中进行了扩展。



净效果是一样的。您可能声称在语言上相等的字符串可以通过不同的字符组合有效地表示。更重要的是,有效性规则在不同文化之间变化。


所有这些都导致了一个基于特殊字符串的包含实现。


using System.Globalization;

public static bool Contains(
         this string source,
         string value,
         CultureInfo culture = null,
         CompareOptions options = CompareOptions.None)
{
    if (value == null)
    {
        throw new ArgumentNullException("value");
    }

    var compareInfo = culture == null ? 
            CultureInfo.CurrentCulture.CompareInfo :
            culture.CompareInfo;

    var sourceEnumerator = StringInfo.GetTextElementEnumerator(source);
    var sequenceEnumerator = StringInfo.GetTextElementEnumerator(value);

    while (sequenceEnumerator.MoveNext())
    {
        if (sourceEnumerator.MoveNext())
        {
            if (!(compareInfo.Compare(
                    sourceEnumerator.Current,
                    sequenceEnumerator.Current,
                    options) == 0))
            {
                sequenceEnumerator.Reset();
            }
        }
        else
        {
            return false;
        }
    }

    return true;
}


无论字符串的规范化如何,此函数都可用于执行不区分大小写,特定于文化的包含。例如


"testable".Contains("EST", StringComparer.CurrentCultureIgnoreCase)

其它参考14


使用RegEx是一种直接的方法:


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

其它参考15


这与此处的其他示例非常相似,但我决定将枚举简化为bool,primary,因为通常不需要其他替代方法。以下是我的示例:


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


用法如下:


if( "main String substring".Contains("SUBSTRING", true) )
....

其它参考16


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

其它参考17


您可以使用string.indexof ()功能。这将不区分大小写

其它参考18


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


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


输出是重置

其它参考19


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
}

其它参考20


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


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

其它参考21


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



  1. 按索引


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

  2. 通过改变案例


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

  3. 由Regex提供


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


其它参考22


新手的简单方法:


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