c# - 不区分大小写'包含(字符串)'




12 Answers

您可以使用String.IndexOf方法并将StringComparison.OrdinalIgnoreCase作为要使用的搜索类型传递:

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);
c# string contains case-insensitive

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

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

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

UPDATE
这个问题是古老的,从那时起我就意识到,如果你想完全研究它,我会要求一个简单的答案来解决一个非常庞大而困难的话题。
对于大多数情况,在单语言的英语代码库中, this答案就足够了。 我怀疑是因为大多数人来到这个类别这是最受欢迎的答案。
然而, This答案提出了一个固有的问题,即我们无法比较文本不区分大小写,直到我们知道两个文本是相同的文化并且我们知道文化是什么。 这可能是一个不太受欢迎的答案,但我认为它更正确,这就是为什么我这样标记它。




使用Regex的替代解决方案:

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

注意

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




答案的一个问题是,如果字符串为null,它将抛出异常。 您可以将其添加为支票,这样就不会:

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



这很简洁。

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



像这样:

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



我知道这不是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");



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

/// <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代码点表示以及哪些有效的字符序列可以表示给定字符串的相关问题,在these answers中扩展了细节。

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

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

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)



这与此处的其他示例非常相似,但我决定将枚举简化为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) )
....



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



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

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

输出是“重置”




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
}



新手的简单方法:

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





Related