대소 문자를 구분하지 않는 '(문자열) 포함'


2907

다음과 같은 결과를 얻을 수있는 방법이 있습니까?

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

케이스 감도를 설정할 수있는 과부하가없는 것 같습니다. 현재 두 가지 모두 대문자입니다. 그러나 그것은 바보입니다 (위로 및 아래로 케이스와 함께 제공 되는 i18n 문제를 참조합니다 ).

업데이트이
질문은 고대 적이며 그 이후로 완전히 조사하기를 원한다면 정말 광범위하고 어려운 주제에 대한 간단한 답변을 요구한다는 것을 깨달았습니다.
대부분의 경우, 단일 언어, 영어 코드 기반에서는 이 답변으로 충분합니다. 여기에 오는 대부분의 사람들이이 카테고리에 속하기 때문에 이것이 가장 인기있는 답변이라고 생각합니다.
이 대답은하지만 우리는 모두 텍스트가 같은 문화를 알고 때까지 우리는 텍스트의 경우를 구분 비교 할 수없는 고유의 문제를 제공하고 우리는 문화가 무엇인지 알고있다. 이것은 덜 인기있는 대답 일 수도 있지만 더 정확하다고 생각하므로 그렇게 표시했습니다.

답변:


1398

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

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

텍스트가 쓰여지는 언어를 설명 culture하는 인스턴스는 어디에 있습니까 CultureInfo?

이 솔루션은 언어에 따라 대소 문자를 구분하지 않는 정의에 대해 투명 합니다 . 예를 들어 영어 는 9 번째 문자 의 문자 I와 i대문자 및 소문자 버전을 사용하는 반면 터키어 는 29 자 길이의 알파벳 의 11 번째 및 12 번째 문자 에이 문자를 사용합니다 . 'i'의 터키어 대문자 버전은 익숙하지 않은 문자 'İ'입니다.

따라서 문자열 tin과 영어TIN 는 같은 단어 이지만 터키어는 다른 단어 입니다 . 내가 이해하는 것처럼, 하나는 '정신'을 의미하고 다른 하나는 의성어입니다. (터크, 내가 틀렸다면 정정하거나 더 좋은 예를 제안하십시오)

요약 하면 텍스트가 어떤 언어인지 아는 경우 '이 두 문자열은 동일하지만 다른 경우에 해당'이라는 질문에만 대답 할 수 있습니다 . 당신이 모른다면, 당신은 펀트를해야합니다. 소프트웨어에서 영어의 패권을 감안할 때 CultureInfo.InvariantCulture친숙한 방식으로 잘못 될 수 있기 때문에 아마 의지해야 합니다.


67
왜 안돼 culture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0? 올바른 문화권을 사용하고 대소 문자를 구분하지 않으며 임시 소문자 문자열을 할당하지 않으며 소문자로 변환 및 비교가 대소 문자를 구분하지 않는 비교와 항상 같은지에 대한 질문을 피합니다.
— Quartermeister

9
이 솔루션은 또한 검색 기능이 필요한 메모리를 할당함으로써 힙을 불필요하게 오염시킵니다
— JaredPar

15
ToLower ()와 비교하면 두 개의 다른 문자가 동일한 소문자를 갖는 경우 대소 문자를 구분하지 않는 IndexOf와 다른 결과를 제공합니다. 예를 들어, U + 0398 "Greek Capital Letter Theta"또는 U + 03F4 "Greek Capital Letter Theta Symbol"에서 ToLower ()를 호출하면 U + 03B8, "Greek Small Letter Theta"가 생성되지만 대문자는 다른 것으로 간주됩니다. 두 솔루션 모두 U + 0073 "Latin Small Letter S"및 U + 017F "Latin Small Letter Long S"와 같은 대문자가 다른 소문자를 고려하므로 IndexOf 솔루션이 더 일관된 것처럼 보입니다.
— Quartermeister

3
@Quartermeister-BTW, .NET 4는 항상 NORM_LINGUISTIC_CASING을 사용하지만 .NET 2는 사용하지 않았기 때문에 .NET 2와 .NET4가 다르게 작동한다고 생각합니다 (이 플래그는 Windows Vista와 함께 나타남).
— Simon Mourier

10
왜 "ddddfg".IndexOf ( "Df", StringComparison.OrdinalIgnoreCase)를 쓰지 않았습니까?
— Chen

2713

당신이 사용할 수있는 경우 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 (2015 VS) 이후, 이전 버전 사용에 대한

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

용법:

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

3
훌륭한 문자열 확장 방법! .IndexOf ()를 수행 할 때 객체 참조 오류가 발생하지 않도록 소스 문자열이 null이 아닌지 확인하기 위해 광산을 편집했습니다.
— Richard Pursehouse

8
이 같은 답변을 제공 paragraph.ToLower(culture).Contains(word.ToLower(culture))과를 CultureInfo.InvariantCulture그리고 지역화 문제가 해결되지 않습니다. 왜 너무 복잡한가? stackoverflow.com/a/15464440/284795
— Panic Colonic

60
@ColonelPanic ToLower버전은 비교 / 검색 작업에 필요하지 않은 2 개의 할당을 포함합니다. 필요하지 않은 시나리오에서 불필요하게 할당하는 이유는 무엇입니까?
— JaredPar

4
@Seabiscuit 그하지 않습니다 작업 때문에 string입니다 IEnumerable<char>따라서 당신이 문자열 찾기 위해 그것을 사용할 수 없습니다
— JaredPar

6
경고 : 기본값 string.IndexOf(string)은 현재 문화권을 사용하는 것이고, 기본값 string.Contains(string)은 서수 비교자를 사용하는 것입니다. 우리가 알듯이, 전자는 더 긴 과부하를 선택하여 변경할 수 있지만 후자는 변경할 수 없습니다. 이 불일치의 결과는 다음 코드 샘플입니다 :Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; string self = "Waldstrasse"; string value = "straße"; Console.WriteLine(self.Contains(value));/* False */ Console.WriteLine(self.IndexOf(value) >= 0);/* True */
— Jeppe의 Stig 닐슨

231

다음 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입니다.


148

정규식을 사용하는 대체 솔루션 :

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

6
좋은 생각, 우리는 RegexOptions에 RegexOptions.IgnoreCase & RegexOptions.IgnorePatternWhitespace & RegexOptions.CultureInvariant;도움이된다면 누구 와 같은 비트 조합을 많이 가지고 있습니다 .
— 사라 바난

7
깔끔하게 IsMatch를 사용하지만이 방법을 선호한다고 말해야합니다.
— wonea

31
더 나쁜 것은 검색 문자열이 정규 표현식으로 해석되기 때문에 많은 문장 부호 문자가 잘못된 결과를 초래하거나 잘못된 표현식으로 인해 예외가 발생한다는 것입니다. 를 검색해보세요 "."에서 "This is a sample string that doesn't contain the search string". 또는 "(invalid"해당 문제를 검색해보십시오 .
— cHao

17
@cHao :이 경우 Regex.Escape도움이 될 수 있습니다. 정규 표현식 IndexOf/ 확장 Contains이 간단하고 분명히 더 명확 할 때 정규식은 여전히 ​​불필요 합니다.
— Dan Mangiarelli

6
이 Regex 솔루션이 최선의 방법임을 암시하지 않았습니다. 나는 단순히 원래 게시 된 질문에 대한 답변 목록에 "다음을 반환하는 방법이 있습니까?"
— Jed

79

항상 문자열을 먼저 대문자 또는 소문자로 지정할 수 있습니다.

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

죄송합니다. 마지막 부분을 보았습니다. 사례를 구분는 것이다 비교 *아마도 *같은 어쨌든을, 성능이 문제가되지 않을 경우, 나는 복사 대문자로 작성하고 그 비교에 문제가 표시되지 않습니다. 나는 한 번 대소 문자를 구분하지 않는 것을 한 번 봤다고 맹세 할 수 있었다 ...


122
"터키 테스트"검색 :)
— Jon Skeet

7
일부 프랑스어 로케일에서 대문자에는 분음 부호가 없으므로 ToUpper ()가 ToLower ()보다 나을 수 있습니다. 대소 문자를 구분하지 않는 비교가 가능하다면 적절한 도구를 사용한다고 말하고 싶습니다.
— 블레어 콘래드

5
의 ToUpper 또는 ToLower는을 사용하지 마십시오 존 소총은 말
— 피터 Gfader

14
2 년 후 다시 이것을보고 새로운 다운 보트를 ... 어쨌든 문자열을 비교하는 더 좋은 방법이 있다는 데 동의합니다. 그러나 모든 프로그램이 현지화되는 것은 아니며 (대부분은 그렇지 않을 수도 있음) 많은 프로그램이 내부 또는 버림받은 앱입니다. 내가 거의 최고의 버리는 애플 리케이션을위한 왼쪽 조언 신용을 기대할 수 있기 때문에 ... 나는에 이동 해요 : D
— 에드 S.

8
"Turkey test"검색은 "TURKEY TEST"검색과 동일합니까?
— JackAce

55

.NET Core 2.0 이상 (현재)

.NET Core는 버전 2.0 이후에 이것을 처리하는 한 쌍의 메소드를 가지고 있습니다.

  • String. 포함 (Char, StringComparison )
  • String.Contains (String, StringComparison )을 포함합니다.

예:

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

시간이 지나면 아마도 .NET 표준으로, 그리고 거기에서 기본 클래스 라이브러리의 다른 모든 구현으로 갈 것입니다.



52

대답의 한 가지 문제는 문자열이 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;
} 

8
toCheck가 빈 문자열 인 경우 포함 문서에 따라 "값 매개 변수가이 문자열 내에서 발생하거나 값이 빈 문자열 (" ")이면 true를 리턴하고 그렇지 않으면 false를 리턴해야합니다."
— amurra

3
위의 amurra의 의견을 바탕으로 제안 된 코드를 수정할 필요가 없습니까? 그리고 이것이 가장 좋은 답변이 먼저되도록 허용 된 답변에 추가되어서는 안됩니까?
— David White

13
이제 소스가 빈 문자열이거나 toCheck가 무엇이든 null이면 true를 반환합니다. 맞지 않습니다. 또한 toCheck가 빈 문자열이고 source가 null이 아닌 경우 IndexOf는 이미 true를 반환합니다. 여기서 필요한 것은 null을 확인하는 것입니다. (source == null || value == null) false를 반환하는 것이 좋습니다.
— Colin

2
소스는 null 수 없습니다
— Lucas

1
if (string.IsNullOrEmpty(source)) return string.IsNullOrEmpty(toCheck);
— Kyle Delaney

35

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

왜 또 다른 추상화 계층을 허용 StringComparison합니까?
— l --''''''--------- '' '' '' '' '' '' ''18:37의

35

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

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

31
그러나 이것은 패턴과 일치합니다. 경우의 예에서, fileNamestr특수 정규식 문자가 (예를 들어 *, +, ., 등) 당신은 꽤 놀랄 것입니다. 이 솔루션을 올바른 Contains기능 처럼 작동하게하는 유일한 방법 은을 fileNamestr수행 하여 탈출 하는 것 Regex.Escape(fileNamestr)입니다.
— XåpplI'-I0llwlg'I-

게다가 정규 표현식을 구문 분석하고 일치시키는 것은 대소 문자를 구분하지 않는 간단한 비교보다 훨씬 더 많은 리소스를 필요로합니다.
— phuclv

29

서수 IgnoreCase, CurrentCultureIgnoreCase 또는 InvariantCultureIgnoreCase?

이것이 누락되었으므로 다음 중 어느 것을 사용해야하는지에 대한 권장 사항이 있습니다.

도스

  • StringComparison.OrdinalIgnoreCase문화권에 구애받지 않는 문자열 일치의 안전한 기본값으로 비교에 사용하십시오 .
  • StringComparison.OrdinalIgnoreCase속도를 높이려면 비교를 사용하십시오 .
  • StringComparison.CurrentCulture-based출력을 사용자에게 표시 할 때 문자열 조작을 사용하십시오 .
  • 비언어적 언어를 사용 StringComparison.Ordinal하거나 StringComparison.OrdinalIgnoreCase비교가
    언어 적으로 관련이없는 경우 (예 : 상징적)로 변하지 않는 문화권을 기반으로 문자열 조작의 현재 사용을 전환 하십시오 .
  • 비교를 위해 문자열을 정규화 할 ToUpperInvariant때보다는 사용하십시오 ToLowerInvariant.

하지마

  • 문자열 비교 메커니즘을 명시 적 또는 암시 적으로 지정하지 않는 문자열 작업에는 오버로드를 사용하십시오.
  • 대부분의 경우 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


당신은 항상 영어 문자열을 얻을 거라는 것을 알고 있다면? 어느 것을 사용해야합니까?
— BKSpurgeon

1
@BKSpurgeon 나는 사건이 중요하지 않은 경우 OrdinalIgnoreCase를 사용합니다
— Fabian Bigler

20

이것이 가장 쉬운 솔루션입니다.

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

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

11

InStr국제화에 관심이 있거나 다시 구현할 수있는 경우 VisualBasic 어셈블리 의 방법이 가장 좋습니다. 그 점을 살펴보면 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

이처럼 :

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

3
이것은 문화별로 다르지 않으며 경우에 따라 실패 할 수 있습니다. culture.CompareInfo.IndexOf (단락, 단어, CompareOptions.IgnoreCase)를 사용해야합니다.
— hikalkan


8

이것을 사용하십시오 :

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

26
질문자는 찾고 Contains있지 않습니다 Compare.
— DuckMaestro

@DuckMaestro, 허용되는 답변은로 구현 Contains됩니다 IndexOf. 따라서이 방법은 똑같이 도움이됩니다! 이 페이지 의 C # 코드 예제 는 string.Compare ()를 사용하고 있습니다. SharePoint 팀의 선택입니다!
— vulcan raven

6

이것은 다른 예제와 매우 유사하지만 일반적으로 다른 대안이 필요하지 않기 때문에 enum을 bool로 단순화하기로 결정했습니다. 내 예는 다음과 같습니다.

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

6

RegEx를 사용하는 방법은 다음과 같습니다.

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

4
귀하의 답변은 guptat59와 정확히 동일하지만 그의 답변에서 지적했듯이 정규 표현식과 일치하므로 테스트중인 문자열에 특수 정규 표현식 문자가 포함되어 있으면 원하는 결과를 얻지 못합니다.
— Casey

2
이것은 이 답변의 전체 사본이며 해당 답변에서 언급 한 것과 동일한 문제로 어려움을 겪고 있습니다
— Liam

동의했다. 정규식 공부
— Jared

5

여기에 대한 답변을 작성하기 위해 문자열 확장 방법을 만들어 좀 더 사용자 친화적으로 만들 수 있습니다.

    public static bool ContainsIgnoreCase(this string paragraph, string word)
    {
        return CultureInfo.CurrentCulture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0;
    }

1
당신의 단락 및 단어를 가정하면 항상 EN-US 될 것이다
— 보리스 CALLENS

3
문화를 en-US로 설정하는 문제를 피하려면 return CultureInfo.CurrentCulture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0;대신 사용하십시오.
— AndrewWhalan 2016 년

3

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

string yourStringForCheck= "abc";
string stringInWhichWeCheck= "Test abc abc";

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

이 부울 값은 문자열이 포함되어 있는지 여부를 반환합니다.



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

2

string.indexof ()기능 을 사용할 수 있습니다 . 대소 문자를 구분하지 않습니다


2

여기서의 트릭은 대소 문자를 무시하고 문자열을 찾는 것이지만 정확히 동일한 대소 문자를 유지하는 것입니다.

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

-4

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

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

잘못된 것만으로 공감하십시오. 제목이 StRiNg이면 어떻게 되나요? StRiNg! = 문자열 및 StRiNg! = STRING
— berniefitz

내가 틀렸어. 다음과 같이 간단하고 간단하게 답변을 편집하십시오. <br/> title.ToLower (). Contains ( "string") // 물론 "string"은 소문자입니다
— O Thạnh Ldt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.