[c#] 대소 문자를 구별하지 않음 'Contains (string)'



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

null 전파에 주목해라 ?. 이전 버전에서는 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);
Question

다음과 같은 사실을 되돌릴 수있는 방법이 있습니까?

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

대소 문자를 구분할 수있는 과부하가없는 것 같습니다. 현재는 둘 다 대문자로 표시되어 있지만, 어리석은 것입니다.

최신 정보
제가 언급하는 어리 석음은 위, 아래 케이스와 관련된 문제입니다.

최신 정보
이 질문은 고대이고 이후로 나는 당신이 그것을 완전히 조사하는 것을 염려한다면 정말로 광대하고 어려운 주제에 대한 간단한 대답을 요구한다는 것을 깨달았습니다.
대부분의 경우, 단일 언어, 영어 코드 기반 this 대답으로 충분합니다. 나는 여기에 오는 대부분의 사람들이이 범주에 속하기 때문에 이것이 가장 대중적인 대답이라고 생각합니다.
그러나이 답은 텍스트가 대문자인지 아닌지를 비교할 수없는 고유 한 문제를 야기합니다. 두 텍스트가 같은 문화이고 우리는 그 문화가 무엇인지 알기까지입니다. 이것은 아마 덜 인기있는 대답이지만, 나는 그것이 더 정확하다고 생각하고 그런 이유로 그것을 표시했습니다.




이 예제는 다른 예제와 매우 비슷하지만 다른 대안은 일반적으로 필요하지 않기 때문에 열거 형으로 열거 형을 단순화하기로 결정했습니다. 여기에 내 예가있다.

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



궁극적으로, 일반적인 "포함"연산은 이와 같은 함수로 내려갑니다.

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

이것은 trivially 같은 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);
    }
}

이제 stringIEnumerable<char> 구현하기 때문에 string 비롯한 모든 시퀀스의 서수 비교를 위해 작동합니다.

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

그러나 우리가 알고 있듯이 문자열은 일반적이지 않고 특수화되어 있습니다. 놀이에 2 개의 중요한 요소가 있습니다.

  1. 자체적으로 다양한 언어 종속적 인 경우가있는 "케이스"문제.
  2. "텍스트 요소"(문자 / 숫자 / 기호 등) 세트가 유니 코드 코드 포인트로 표현되는 방식과 주어진 문자열을 나타낼 수있는 유효한 문자 시퀀스가 ​​무엇인지에 관한 오히려 관련된 문제는 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)



string.indexof () 함수를 사용할 수 있습니다. 대소 문자를 구별하지 않습니다.




해답이있는 한 가지 문제점은 문자열이 null 인 경우 예외를 throw한다는 것입니다. 수표로 추가하여 다음과 같이 할 수 있습니다.

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를 사용하는 대체 솔루션 :

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

주의

@cHao가 그의 의견에서 지적한 바와 같이,이 솔루션이 잘못된 결과를 반환하게하는 시나리오가 있습니다. 이 솔루션을 우연히 구현하기 전에 수행중인 작업을 알고 있는지 확인하십시오.




다음과 같이하십시오.

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



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
}



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



이것은 깨끗하고 단순합니다.

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



초보자를위한 간단한 방법 :

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



Related