대소 문자를 구분하지 않는 문자열 비교를 어떻게 할 수 있습니까?


217

아래의 대소 문자를 구분하지 않으려면 어떻게해야합니까?

drUser["Enrolled"] = 
      (enrolledUsers.FindIndex(x => x.Username == (string)drUser["Username"]) != -1);

나는 오늘 사용하기를 제안하는 몇 가지 조언을 받았다.

x.Username.Equals((string)drUser["Username"], StringComparison.OrdinalIgnoreCase)));

문제는이 작업을 수행 할 수 없다는 것입니다. 아래 줄을 시도했지만이 컴파일하지만 잘못된 결과를 반환합니다. 등록 된 사용자를 등록 된 사용자와 등록되지 않은 사용자로 반환합니다.

drUser["Enrolled"] = 
      (enrolledUsers.FindIndex(x => x.Username.Equals((string)drUser["Username"], 
                                 StringComparison.OrdinalIgnoreCase)));

누구든지 문제를 지적 할 수 있습니까?


1
어떤 데이터 유형이어야 drUser["Enrolled"]합니까? 부울 값처럼 보이지만 FindIndex()인덱스를 반환합니다. 해당 사용자의 색인이 0이면 0을 리턴하며 이는 거짓 일 수 있습니다. 실제로는 사실이다. Exists()방법은이 경우에 더 좋을 수 있습니다.
drharris

한 필드에서 다른 필드에없는 서식 또는 여분의 공간이 없는지 확실합니까?
joshlrogers 2016 년

1
FindIndex (및 테스트) 대신 enrolledUsers.Any ()를 사용하는 것이 좋습니다.
Marc

답변:


405

이것은 .NET 프레임 워크 (4 & +)에서 평등을 확인하는 가장 좋은 방법은 아닙니다.

String.Compare(x.Username, (string)drUser["Username"], 
                  StringComparison.OrdinalIgnoreCase) == 0

대신 다음을 사용하십시오

String.Equals(x.Username, (string)drUser["Username"], 
                   StringComparison.OrdinalIgnoreCase) 

MSDN은 다음을 권장합니다.

  • 두 문자열이 같은지 테스트하려면 String.Equals 메서드의 오버로드를 사용하십시오.
  • String.CompareString.CompareTo 메소드를 사용하여 문자열이 같지 않고 문자열을 정렬 하십시오 .

8
string.Compare아닌을 사용해야합니다 String.Compare.
Fred

5
@Fred 동의하지만 그 이유를 확인할 수 있습니까?
Gusdor

22
@Fred 나는 'Stylecop가 그렇게 말했기 때문에'기술적 인 이유를 기대하고있었습니다. 뭔가 빠졌습니까?
Gusdor

12
string.Compare, 문자열 동의어 System.String 클래스와 차이가 없습니다. 회원 비교는 확장 방법입니다. @ Fred @Gusdor
Nuri YILMAZ 2016 년

23
@Gusdor stringString언어 키워드이므로 사용하는 것이 좋습니다 . 하나 String는 아닌 다른 것이 될 수 System.String있지만 string그렇지는 않습니다. 또한 stringC #에 존재하는 것이 다소 보장되는 반면 String기술적으로는 C #이 아닌 .NET의 일부입니다.
Dave Cousineau

36

String.Compare다음과 같은 정적 기능을 사용해야합니다

x => String.Compare (x.Username, (string)drUser["Username"],
                     StringComparison.OrdinalIgnoreCase) == 0

6
아니요, String.Equals대신 사용해야 합니다 String.Compare. 어느 것이 더 큰지 계산할 필요는 없습니다. 단지 그것들이 같지 않다는 것입니다.
ErikE

@ErikE : 6 년 후에 사용하기를 권장하는 방법이 궁금합니다 :-)
Oleg

3
궁금하지 않습니다! 평등 시맨틱을 원할 때 평등을 사용하고 비교 시맨틱을 원할 때 비교를 사용하는 것이 좋습니다. 그게 어려워요? IEquatableIComparable같은 일을하지 마십시오, 당신은 하나를 구현하지만,하는 것이 다른 구현 NO 감각을 만들 것 클래스를 가질 수 있습니다. 예를 들어, 센서 샘플링이 동일하지 않은 시간 (IComparable)으로 센서 샘플링을 주문할 수 있습니다. 그리고 사물이 같은지 (IEquatable) 여부를 표시 할 수 있지만 주문하는 것은 의미가 없습니다 (예 : 컴퓨터 일련 번호).
ErikE

@ 에릭 : 당신은 내 관점을 이해하지 못합니다. 이전 답변은 글을 쓰는 시간에 해당합니다. 오래된 답변을 건 드리면 안됩니다. 대부분의 제품에 대해 사실입니다. 성능 관점에서 모범 사례 또는 최선의 선택은 나중에 여러 번 변경할 수 있습니다. 나는 오래된 대답에 대해 토론하는 것이 의미가 없습니다.
Oleg

18
내 사과, 나는 내 의견의 정확성에 대한 비판으로 받아 들였다. 당신이 말하는 것은 당신이 당신의 이전 답변이 최선의 답변이 아닐 수도 있음을 인정한다는 것입니다! 그러나 나는 오래된 답변에 대해 당신과 동의하지 않아야합니다. 빈약 한 정보를 제공 올드 답변 해야 댓글을 달 수는 해야한다 그들은 여전히 알리는 때문에 수, 다운 투표 오늘날의 독자.
ErikE

27

비교를 위해 이것을 사용하십시오 :

string.Equals(a, b, StringComparison.CurrentCultureIgnoreCase);

10
CurrentCultureIgnoreCase와 OrdinalIgnoreCase를 사용할 때의 장점과 함정에주의하십시오. 문화 비교의 의미가 필요하지 않으면 성능을 저장하고 서수 비교를 사용하십시오.
ErikE

7

다른 답변은 여기에서 완전히 유효하지만 어떻게 든 입력 StringComparison.OrdinalIgnoreCase하고 사용 하는 데 시간이 걸립니다 String.Compare.

간단한 문자열 확장 방법을 코딩했습니다. 여기서 비교가 대소 문자를 구분하는지 부울을 사용하여 대소 문자를 구분하지 않는지 지정할 수 있습니다. 여기에서 전체 코드 스 니펫을 첨부하십시오.

using System;

/// <summary>
/// String helpers.
/// </summary>
public static class StringExtensions
{
    /// <summary>
    /// Compares two strings, set ignoreCase to true to ignore case comparison ('A' == 'a')
    /// </summary>
    public static bool CompareTo(this string strA, string strB, bool ignoreCase)
    {
        return String.Compare(strA, strB, ignoreCase) == 0;
    }
}

그 후 전체 비교는 대략 10 자로 줄어 듭니다.

문자열 확장을 사용하기 전에 :

String.Compare(testFilename, testToStart,true) != 0

문자열 확장을 사용한 후 :

testFilename.CompareTo(testToStart, true)

2
이름 지정에 동의하지 않습니다. 비교는 소프트웨어 개발자에게 잘 알려진 기능이며 기본적으로 기능이 변경되었습니다. 비교와 같은 정수를 반환하거나 이름을 'IsEqual'과 같은 다른 이름으로 변경해야한다고 생각합니다.
Fred

7

System.String대소 문자를 구분하지 않는 비교 확장 방법을 제공하기 위해 확장 할 수 있습니다 (논쟁이지만) .

public static bool CIEquals(this String a, String b) {
    return a.Equals(b, StringComparison.CurrentCultureIgnoreCase);
}

다음과 같이 사용하십시오.

x.Username.CIEquals((string)drUser["Username"]);

C #을 사용하면 프로젝트에서 구문 설탕으로 사용할 수있는 확장 메서드를 만들 수 있습니다.

답이 아니며이 질문이 오래되어 해결되었음을 알고 있습니다.이 비트를 추가하고 싶었습니다.


3

이 링크에서 더 많은 정보를 찾을 수 있다고 생각합니다.

http://codeidol.com/community/dotnet/controlling-case-sensitivity-when-comparing-two-st/8873/

String 클래스에서 Compare 정적 메소드를 사용하여 두 문자열을 비교하십시오. 비교가 대소 문자를 구분하는지 여부는 과부하 중 하나의 세 번째 매개 변수에 의해 결정됩니다. 예를 들면 다음과 같습니다.

string lowerCase = "abc";
string upperCase = "AbC";
int caseInsensitiveResult = string.Compare(lowerCase, upperCase,
  StringComparison.CurrentCultureIgnoreCase);
int caseSensitiveResult = string.Compare(lowerCase,
  StringComparison.CurrentCulture);

caseSensitiveResult 값은 -1 (lowCase가 upperCase보다 작음을 나타냄)이고 caseInsensitiveResult가 0입니다 (lowCase가 upperCase와 같음을 나타냄).


1

StringComparison.CurrentCultureIgnoreCase대신 에 사용 하는 것은 어떻습니까?


5
-1 :이 답변이 충분하지 않습니다. @ ocean4dream의 답변 : stackoverflow.com/a/13965429/109941을 참조하십시오 .
Jim G.

@decyclone : OrdinalIgnoreCase보다 느리지 만 경우에 따라 관련성이 있습니다. 따라서 나는 -1을주지 않을 것입니다. stackoverflow.com/questions/2749662/…
Csaba Toth


1

EqualsIgnoreCase에 대한 확장 메소드를 작성하고 싶습니다.

public static class StringExtensions
{
    public static bool? EqualsIgnoreCase(this string strA, string strB)
    {
        return strA?.Equals(strB, StringComparison.CurrentCultureIgnoreCase);
    }
}

-11

항상 함수를 사용할 수 있습니다. .ToLower (); .ToUpper ();

문자열을 변환 한 다음 비교하십시오 ...

행운을 빕니다


나는 이것이 그의 문제를 해결할 것이라고 생각하지 않는다. 또한이 질문이 이미 4 살 이상되었음을 표시하십시오.
Vojtěch Dohnal

7
이것은 새로운 문자열을 생성하므로 매우 비효율적이라고 생각합니다. 이 새 문자열을 만들려면 모든 문자를 확인하고 원하는 대소 문자로 변환하므로 비교는 모든 문자를 다시 확인해야합니다. 따라서 더 많은 메모리와 처리 능력을 사용합니다.
Air2

5
이것은 메모리 할당 때문에 매우 나쁜 습관입니다.
Thorbjørn Lindeijer

이것은 불필요한 메모리 할당 및 비효율적 일뿐만 아니라; 또한 터키 테스트에 실패했습니다 .
dmitry December
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.