c# 찾기 - 대소 문자를 구별하지 않음 'Contains(string)'




대소문자 문자열 (21)

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

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

대소 문자 구분을 설정할 수있는 과부하가없는 것 같습니다. 현재는 둘 다 대문자로 표시되어 있지만, 이는 바보입니다 (위아래 대소 문자와 함께 나타나는 i18n 문제를 언급 한 것입니다).

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


Answers

전달 된 문자열이 문자열에 있는지 확인하려는 경우 간단한 방법이 있습니다.

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

문자열 paragraph 에 문자열 word 가 포함되어 있는지 테스트하려면 (Thanks @QuarterMeister)

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

여기서 culture 는 텍스트가 작성된 언어를 설명하는 CultureInfo 의 인스턴스입니다.

이 솔루션은 대소 문자가 구분되지 않는 언어의 정의에 대해 투명 합니다 . 예를 들어 영어에서는 9 번째 문자의 대 / 소문자 버전에 Ii 문자를 사용하지만 터키어에서는 29 자 문자 알파벳11 번째 및 12 번째 문자 에이 문자를 사용합니다. 'i'의 터키 대문자 버전은 익숙하지 않은 문자 'İ'입니다.

따라서 문자열 tinTIN영어 에서는 같은 단어이지만 터키어 에서는 다른 단어 입니다 . 내가 알기에, 하나는 '정신'을 의미하고 다른 하나는 의성어 단어입니다. (투르크 인들, 제가 틀렸다면 저를 시정 해 주시고, 더 좋은 예를 제안하십시오)

요약하면, 텍스트가있는 언어를 아는 경우에만 '이 두 문자열은 동일하지만 다른 경우에'질문에 대답 할 수 있습니다. 모르는 사람은 펀 트배를해야합니다. 소프트웨어에서 영어의 헤게모니를 감안할 때, CultureInfo.InvariantCulture 에 익숙해야합니다. 친숙한 방식으로 잘못 될 것이기 때문입니다.


항상 문자열을 먼저 올리거나 내릴 수 있습니다.

string title = "string":
title.ToUpper().Contains("STRING")  // returns 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)

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

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

이것을 사용하십시오 :

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

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


다음과 같이 IndexOf() 사용할 수 있습니다 :

string title = "STRING";

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

0 (영)은 인덱스가 될 수 있으므로 -1에 대해 확인합니다.

MSDN

해당 문자열이있는 경우 값의 0부터 시작하는 인덱스 위치이며, 그렇지 않으면 -1입니다. value가 String.Empty이면 반환 값은 0입니다.


이것들이 가장 쉬운 해결책입니다.

  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.IsMatch(title, "string", RegexOptions.IgnoreCase);
    

다음과 같이하십시오.

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

.NET Core 2.0 이상 (현재)

.NET Core에는 버전 2.0부터이 문제를 처리 할 수있는 두 가지 방법이 있습니다.

  • String.Contains (Char, StringComparison )
  • String.Contains (String, StringComparison )

예:

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

시간이 지나면 .NET 표준에, 그리고 그 곳에서 기본 클래스 라이브러리의 다른 모든 구현으로 이동하게 될 것입니다.


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

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

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

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

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
}

나는 이것이 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");

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

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

RegEx를 사용하면이 작업을 수행 할 수 있습니다.

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

해답이있는 한 가지 문제점은 문자열이 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;
} 

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

기본적으로 ignorecase 를 설정할 수 있습니다. 이것을 쉘에서 실행하십시오.

echo "set ic" >> ~/.vimrc




c# string contains case-insensitive