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


2907

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

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

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

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

답변:


1398

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

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

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

이 솔루션은 언어에 따라 대소 문자를 구분하지 않는 정의에 대해 투명 합니다 . 예를 들어 영어 는 9 번째 문자 의 문자 Ii대문자 및 소문자 버전을 사용하는 반면 터키어 는 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.