2009-09-08 9 views
36

모든 문화권에서 작동하는 대소 문자를 무시하고 두자를 비교하는 올바른 방법이 궁금합니다. 또한, 대소 문자를 무시하지 않고 두 문자를 테스트하는 가장 좋은 방법은 Comparer<char>.Default입니까? 사로 게이트 쌍에 대해이 작업이 가능합니까?대소 문자 무시 대소 문자를 비교하는 올바른 방법은 무엇입니까?

편집 : 추가 샘플 IComparer<char> 구현

는이 나는, "문자열 A"

public class CaseInsensitiveCharComparer : IComparer<char> { 
    private readonly System.Globalization.CultureInfo ci; 
    public CaseInsensitiveCharComparer(System.Globalization.CultureInfo ci) { 
     this.ci = ci; 
    } 
    public CaseInsensitiveCharComparer() 
     : this(System.Globalization.CultureInfo.CurrentCulture) { } 
    public int Compare(char x, char y) { 
     return Char.ToUpper(x, ci) - Char.ToUpper(y, ci); 
    } 
} 

// Prints 3 
Console.WriteLine("This is a test".CountChars('t', new CaseInsensitiveCharComparer())); 
+0

현재 배양에 대하여 올바른 대문자로 변환 숯의 ToUpper 수 있지만 리턴 어휘 순서가 정확하지 않다. 아마도 이것은 .NET에서 문자열 비교를 위해서만 지원됩니다. – Holstebroe

답변

63

을 위해 작동합니다) 사실 난 문화 ". "i"와 "I"가 터키에서도 평등 해지기를 원하십니까?

bool equal = char.ToUpperInvariant(x) == char.ToUpperInvariant(y); 

을 ... 그러나 나는 확실하지 않다 "작품"에 대한 이해에 의해 모든 문화에 따라 그 "작품"여부 :

당신은 사용할 수 있습니다.

물론 두 문자를 모두 문자열로 변환 한 다음 문자열에서 원하는 비교를 수행 할 수 있습니다. 어쨌든 실현 될 수 없습니다 단일 char이 없기 때문에, 서로 게이트 쌍에 대한

bool equal = x.ToString().Equals(y.ToString(), 
           StringComparison.InvariantCultureIgnoreCase); 

하는 Comparer<char> : 다소 덜 효율적하지만, 당신이 프레임 워크에서 사용할 수있는 비교의 모든 범위를 제공 않는다 . 그래도 Comparer<int>을 만들 수 있습니다. 기본값을 사용

+0

그게 내가 네 예제 모두에서 그렇게 생각한 방법이지만, 프레임 워크가 제공하는 것으로 알려지지 않은 더 나은 방법이있을 수 있다고 생각했다. String.Contains (char, IEqualityComparer ) –

+1

에 대한 LINQ 확장 메서드의 컨텍스트에서 생각하고있었습니다.이 메서드에 대한 프레임 워크 메서드는 없습니다. 문자열 비교는 실제로 Compareer 구현으로의 드롭 다운이 아니라 네이티브 메서드를 사용하여 구현됩니다. –

+0

@TimSchmelter : 아니요, 어떤 이유로 든 그것을 놓칠 수있었습니다. 끝에 간단한 메모를 추가했습니다. –

1

string.Compare ("문자열 A"를 사용하기로 결정했습니다 것입니다 사람을 도움이된다면,

그것은 그것은 당신이 알에 대한 작업 "무슨 뜻에 따라 모든 문자열

+1

안녕하세요 세르지오, 문자열 인스턴스가 아닌 두 개의 문자 인스턴스를 비교하는 방법을 알아 보았습니다. 대/소문자를 무시하는 Comparer 구현을 찾고 있습니다. –

+8

이것은 영어권 국가에서 잘 작동합니다. 그러나 동유럽의 어느 누구도 사용자가 작성한 응용 프로그램을 사용하지 않습니다. –

+2

@ 존 그랜트 : 저는 포르투갈 (포르투갈)에서 이것을 사용합니다. 포르투갈어는 "이상한"문자가 많은 라틴어 기반 언어입니다. 그것은 완벽하게 작동합니다. – Sergio

12

문화 (즉 하지 불변입니다) :

if (char.ToLower(ch1) == char.ToLower(ch2)) 
{ .... } 

또는 문화를 지정 : 나는 그것을 알고있는 것처럼

CultureInfo myCulture = ...; 
if (char.ToLower(ch1, myCulture) == char.ToLower(ch2, myCulture)) 
{ .... } 
+0

나는 다운 투표를 할 수는 없지만, 당신의 해결책이 적절하게 답변되었다고 생각하는만큼 나는 당신에게 업 그레 이드를 제공했습니다. –

+0

이것은 질문에 대한 대답이 아닙니다. –

+0

존 (Jon)은 동의했지만, 나는 "모든 문화에 효과가있을 것"이라는 말을 조금 지나치게 낙관적이고 비현실적인 것으로 읽었다. 나는 명백한 진술을해야했다. –

2

이 정말 방법이없는 그 "모든 문화권에서 효과가 있습니다." 어떤 종류의 내부, 표시되지 않는 사용자 사유 (이 경우 InvariantCulture를 사용해야 함) 또는 사용자의 CurrentCulture를 사용하려는 경우 문자를 비교하려고합니다. 분명히 사용자의 현재 문화권을 사용하면 다른 로케일에서 다른 결과를 얻게되지만 해당 로케일의 사용자가 기대하는 것과 일관됩니다.

두 문자를 비교하는 이유에 대해 알지 못하면 어떤 문자를 사용해야하는지 정말로 알 수 없습니다.

class Test{ 
    static int Compare(char t, char p){ 
     return string.Compare(t.ToString(), p.ToString(), StringComparison.CurrentCultureIgnoreCase); 
    } 
} 

을하지만이 그것을 할 수있는 "최적의"방법입니다 의심하지만 난 당신이 체크해야하는 모든 경우를 아니에요 ... :

+0

Jon, 일반적인 질문입니다. 유니 코드에 능숙하지 않으며 여기에 질문을 제기 할 것이라고 생각합니다. LINQ가 제공하는 String.Contains (char, IEqualityComparer ) 확장 메서드를 고려해보십시오. 대/소문자를 구분하지 않도록 구현하는 올바른 방법은 무엇입니까? –

+0

다시 말하지만, 실제로 데이터가 무엇이고 왜 그것을 비교했는지에 달려 있습니다. 예를 들어 일들을 일정한 순서로 정렬하기를 원한다면, 다양한 불변량 비교를 사용하면됩니다. 사용자 입력에 응답하는 경우 해당 사용자의 문화권을 사용하여 예상 한 결과를 제공하는 것이 좋습니다. 나는 정말로 "하나의 크기가 모두 맞는"대답이 있는지 확신하지 못합니다. –

+0

내 Comparer 구현이 대답으로 제공된 것이 올바른 접근 방법이라고 생각하십니까? –

0

당신은 시도 할 수내가 그 런타임에서 사용할 수있는 것 생각하는 것은

0

내가 대문자를 비교하는 것이 좋습니다 다음

public class CaseInsensitiveCharComparer : IComparer<char> { 
    private readonly System.Globalization.CultureInfo ci; 
    public CaseInsensitiveCharComparer(System.Globalization.CultureInfo ci) { 
     this.ci = ci; 
    } 
    public CaseInsensitiveCharComparer() 
     : this(System.Globalization.CultureInfo.CurrentCulture) { } 
    public int Compare(char x, char y) { 
     return Char.ToUpper(x, ci) - Char.ToUpper(y, ci); 
    } 
} 

// Prints 3 
Console.WriteLine("This is a test".CountChars('t', new CaseInsensitiveCharComparer())); 
+1

뺄셈에 의한 char 비교가 앞으로의 CLR 버전에서 계속 올바른 것으로 가정하는 것은 위험하므로, 대신에'return Char.ToUpper (x, ci) .CompareTo (Char.ToUpper (y, ci)); . –

+0

@MattHowells 나는 그것을 주장 할 것이다 ... see'char.CompareTo (char)':'return (m_value-value);' –

0

같은이며, 그들은 단지의 경우, 로케일의 uppercasing에, 소문자를 비교 한 후 일치하지 않는 경우 lowercasing 로직은 약간 다르게 동작합니다.

부록 예

,

int CompareChar(char c1, char c2) 
{ 
    int dif; 

    dif = char.ToUpper(c1) - char.ToUpper(c2); 
    if (diff != 0) 
     dif = char.ToLower(c1) - char.ToLower(c2); 
    return dif; 
} 
관련 문제