Programing

InvariantCulture와 서수 문자열 비교의 차이점

lottogame 2020. 2. 12. 07:57
반응형

InvariantCulture와 서수 문자열 비교의 차이점


c #에서 두 문자열이 동일한 지 비교할 때 InvariantCulture와 서수 비교의 차이점은 무엇입니까?


불변의 문화

"표준"문자 순서 세트 (a, b, c, ... 등)를 사용합니다. 이것은 ( 'A-과 급성'전에 할 수있다 다른 순서의 문자를 정렬 할 수 있습니다 일부 특정 로케일, 대조적이다 또는 'A'는 지역에 따라, 등등 후).

서수

반면에 문자를 나타내는 원시 바이트 값을 순전히 살펴 봅니다.


http://msdn.microsoft.com/en-us/library/e6883c06.aspx 에는 다양한 StringComparison 값의 결과를 보여주는 훌륭한 샘플이 있습니다. 마지막에, 그것은 (발췌) 보여줍니다 :

StringComparison.InvariantCulture:
LATIN SMALL LETTER I (U+0069) is less than LATIN SMALL LETTER DOTLESS I (U+0131)
LATIN SMALL LETTER I (U+0069) is less than LATIN CAPITAL LETTER I (U+0049)
LATIN SMALL LETTER DOTLESS I (U+0131) is greater than LATIN CAPITAL LETTER I (U+0049)

StringComparison.Ordinal:
LATIN SMALL LETTER I (U+0069) is less than LATIN SMALL LETTER DOTLESS I (U+0131)
LATIN SMALL LETTER I (U+0069) is greater than LATIN CAPITAL LETTER I (U+0049)
LATIN SMALL LETTER DOTLESS I (U+0131) is greater than LATIN CAPITAL LETTER I (U+0049)

InvariantCulture 수율 (U + 0069, U + 0049, U + 00131), 서수 수율 (U + 0049, U + 0069, U + 00131)이있는 곳을 확인할 수 있습니다.


예를 들어, 캐릭터 확장이라는 것이 있습니다.

var s1 = "Strasse";
var s2 = "Straße";

s1.Equals(s2, StringComparison.Ordinal);           //false
s1.Equals(s2, StringComparison.InvariantCulture);  //true

InvariantCultureß 문자를 사용 하면 ss로 확장됩니다.


가리키며 은 .NET Framework의 문자열을 사용하기위한 모범 사례 :

  • 문화권에 구애받지 않는 문자열 일치의 안전한 기본값으로 StringComparison.Ordinal또는 StringComparison.OrdinalIgnoreCase비교에 사용하십시오 .
  • 더 나은 성능을 위해 StringComparison.Ordinal또는 StringComparison.OrdinalIgnoreCase더 나은 성능을 위해 비교를 사용하십시오 .
  • 비교가 언어 적으로 관련이없는 경우 (예 : 상징적)를 기준으로 문자열 조작 대신 비 언어 StringComparison.Ordinal또는 StringComparison.OrdinalIgnoreCase값을 사용하십시오 CultureInfo.InvariantCulture.

그리고 마지막으로:

  • StringComparison.InvariantCulture대부분의 경우를 기준으로 문자열 연산을 사용하지 마십시오 . 몇 가지 예외 중 하나는 언어 적으로 의미가 있지만 문화적으로 불가지론적인 데이터를 유지하는 경우입니다.

또 다른 편리한 차이점은 (영어에서 악센트가 드문 경우) InvariantCulture 비교는 전체 문자열을 대소 문자를 구분하지 않고 먼저 비교 한 다음 필요에 따라 (필요한 경우) 구별 문자 만 비교 한 후 대소 문자를 구분한다는 것입니다. (대소 문자를 구분하지 않는 대소 문자 구분 비교도 가능합니다.) 대소 문자를 구분하지 않습니다 .악센트 문자는 동일한 문자의 또 다른 풍미로 간주되며 문자열은 먼저 악센트를 무시한 다음 일반 문자가 모두 일치하는 경우 해당 문자를 고려합니다 (대소 문자를 구분하지 않는 비교에서 궁극적으로 무시되지 않는 경우를 제외하고는 대소 문자가 다름). 이 단어들은 첫 번째 억양 차이에서 완전히 분리되지 않고 서로 가까이있는 다른 단어의 억양 버전을 그룹화합니다. 이것은 사전에서 일반적으로 찾을 수있는 정렬 순서이며 대문자로 된 단어는 소문자와 바로 옆에 나타나고 악센트 부호 문자는 해당하는 액센트가없는 문자 근처에 있습니다.

서수 비교는 숫자 값을 엄격하게 비교하여 첫 번째 차이에서 멈 춥니 다. 이렇게하면 대문자와 소문자가 완전히 분리되어 (대소 문자와 악센트 문자가 구분됨) 대문자로 된 단어는 소문자와 거의 일치하지 않습니다.

InvariantCulture는 또한 대문자가 소문자보다 큰 것으로 간주하는 반면, Ordinal은 대문자가 소문자보다 작은 것으로 간주합니다 (컴퓨터는 소문자를 사용하기 전 예전의 ASCII 보류, 대문자가 먼저 할당되어 소문자보다 낮은 값을 가짐) 나중에 추가).

예를 들어, 서수 : "0" < "9" < "A" < "Ab" < "Z" < "a" < "aB" < "ab" < "z" < "Á" < "Áb" < "á" < "áb"

그리고 InvariantCulture에 의해 : "0" < "9" < "a" < "A" < "á" < "Á" < "ab" < "aB" < "Ab" < "áb" < "Áb" < "z" < "Z"


문제는 평등관한 것이지만, 빠른 시각적 참조를 위해 여기서 일부 특질을 보여주는 몇 가지 문화를 사용하여 일부 문자열의 순서를 정렬 했습니다.

Ordinal          0 9 A Ab a aB aa ab ss Ä Äb ß ä äb ぁ あ ァ ア 亜 A
IgnoreCase       0 9 a A aa ab Ab aB ss ä Ä äb Äb ß ぁ あ ァ ア 亜 A
--------------------------------------------------------------------
InvariantCulture 0 9 a A A ä Ä aa ab aB Ab äb Äb ss ß ァ ぁ ア あ 亜
IgnoreCase       0 9 A a A Ä ä aa Ab aB ab Äb äb ß ss ァ ぁ ア あ 亜
--------------------------------------------------------------------
da-DK            0 9 a A A ab aB Ab ss ß ä Ä äb Äb aa ァ ぁ ア あ 亜
IgnoreCase       0 9 A a A Ab aB ab ß ss Ä ä Äb äb aa ァ ぁ ア あ 亜
--------------------------------------------------------------------
de-DE            0 9 a A A ä Ä aa ab aB Ab äb Äb ß ss ァ ぁ ア あ 亜
IgnoreCase       0 9 A a A Ä ä aa Ab aB ab Äb äb ss ß ァ ぁ ア あ 亜
--------------------------------------------------------------------
en-US            0 9 a A A ä Ä aa ab aB Ab äb Äb ß ss ァ ぁ ア あ 亜
IgnoreCase       0 9 A a A Ä ä aa Ab aB ab Äb äb ss ß ァ ぁ ア あ 亜
--------------------------------------------------------------------
ja-JP            0 9 a A A ä Ä aa ab aB Ab äb Äb ß ss ァ ぁ ア あ 亜
IgnoreCase       0 9 A a A Ä ä aa Ab aB ab Äb äb ss ß ァ ぁ ア あ 亜

관찰 :

  • de-DE, ja-JP그리고 en-US정렬 같은 방법으로
  • Invariant단지 종류 ssß다르게 위의 세 가지 문화
  • da-DK 상당히 다르게 정렬
  • IgnoreCase모든 샘플링 문화에 대한 플래그 사항

위의 테이블을 생성하는 데 사용되는 코드 :

var l = new List<string>
    { "0", "9", "A", "Ab", "a", "aB", "aa", "ab", "ss", "ß",
      "Ä", "Äb", "ä", "äb", "あ", "ぁ", "ア", "ァ", "A", "亜" };

foreach (var comparer in new[]
{
    StringComparer.Ordinal,
    StringComparer.OrdinalIgnoreCase,
    StringComparer.InvariantCulture,
    StringComparer.InvariantCultureIgnoreCase,
    StringComparer.Create(new CultureInfo("da-DK"), false),
    StringComparer.Create(new CultureInfo("da-DK"), true),
    StringComparer.Create(new CultureInfo("de-DE"), false),
    StringComparer.Create(new CultureInfo("de-DE"), true),
    StringComparer.Create(new CultureInfo("en-US"), false),
    StringComparer.Create(new CultureInfo("en-US"), true),
    StringComparer.Create(new CultureInfo("ja-JP"), false),
    StringComparer.Create(new CultureInfo("ja-JP"), true),
})
{
    l.Sort(comparer);
    Console.WriteLine(string.Join(" ", l));
}

불변은 언어 적으로 적절한 유형의 비교입니다.
서수는 이진 유형의 비교입니다. (빠르게)
를 참조하십시오 http://www.siao2.com/2004/12/29/344136.aspx를


다음은 InvariantCultureIgnoreCase 및 OrdinalIgnoreCase를 사용한 문자열 동등 비교가 동일한 결과를 제공하지 않는 예입니다.

string str = "\xC4"; //A with umlaut, Ä
string A = str.Normalize(NormalizationForm.FormC);
//Length is 1, this will contain the single A with umlaut character (Ä)
string B = str.Normalize(NormalizationForm.FormD);
//Length is 2, this will contain an uppercase A followed by an umlaut combining character
bool equals1 = A.Equals(B, StringComparison.OrdinalIgnoreCase);
bool equals2 = A.Equals(B, StringComparison.InvariantCultureIgnoreCase);

이를 실행하면 equals1은 false가되고 equals2는 true가됩니다.


차이점을 보여주기 위해 멋진 유니 코드 문자 exmaples를 사용할 필요가 없습니다. 오늘 내가 찾은 간단한 예가 ASCII 문자로만 구성된 놀라운 예입니다.

ASCII 테이블에 따르면, 일반적으로 비교할 때 0(0x48)이 _(0x95) 보다 작습니다 . InvariantCulture는 반대라고 말합니다 (아래 PowerShell 코드).

PS> [System.StringComparer]::Ordinal.Compare("_", "0")
47
PS> [System.StringComparer]::InvariantCulture.Compare("_", "0")
-1

항상 오버로드로 허용하는 문자열 메소드에서 InvariantCulture를 사용하십시오. InvariantCulture를 사용하면 안전합니다. 많은 .NET 프로그래머가이 기능을 사용하지 않을 수도 있지만 다른 문화권에서 소프트웨어를 사용할 경우 InvariantCulture는 매우 편리한 기능입니다.

참고 URL : https://stackoverflow.com/questions/492799/difference-between-invariantculture-and-ordinal-string-comparison



반응형