IT박스

대소 문자를 구분하지 않는 문자열 비교

itboxs 2020. 11. 26. 08:05
반응형

대소 문자를 구분하지 않는 문자열 비교


두 변수를 비교하여 동일한 지 확인하고 싶지만이 비교는 대소 문자를 구분하지 않기를 원합니다.

예를 들어 다음은 대소 문자를 구분합니다.

if($var1 == $var2){
   ...
}

그러나 대소 문자를 구분하지 않기를 원합니다. 어떻게 접근할까요?


이것은 매우 간단합니다. strtolower()두 변수를 모두 호출 하면됩니다.

유니 코드 또는 국제 문자 집합을 처리해야하는 경우 mb_strtolower().

다른 답변은 사용을 제안합니다. strcasecmp()이 함수 는 멀티 바이트 문자를 처리하지 않으므로 UTF-8 문자열에 대한 결과는 가짜입니다.


strcasecmp() 문자열이 동일한 경우 (대소 문자 변형 제외) 0을 반환하므로 다음을 사용할 수 있습니다.

if (strcasecmp($var1, $var2) == 0) {
}

문자열이 단일 바이트 인코딩이면 간단합니다.

if(strtolower($var1) === strtolower($var2))

문자열이 UTF-8 인 경우 유니 코드의 복잡성을 고려해야합니다. to-lower-case 및 to-upper-case는 bijective 함수가 아닙니다. 즉, 소문자가있는 경우 대문자로 변환하고 변환합니다. 다시 소문자로 돌아 가면 동일한 코드 포인트로 끝나지 않을 수 있습니다 (대문자로 시작하는 경우에도 마찬가지입니다).

  • "İ"( Latin Capital Letter I with Dot Above, U+0130)는 대문자이며 "i"( Latin Small Letter I, U+0069)는 소문자 변형이며 "i"의 대문자 변형은 "I"( Latin Capital Letter I, U+0049)입니다.
  • "ı"( Latin Small Letter Dotless I, U+0131)는 소문자이며 "I"( Latin Capital Letter I, U+0049)는 대문자 변형이며 "I"의 소문자 변형은 "i"( Latin Small Letter I, U+0069)입니다.

따라서 mb_strtolower('ı') === mb_strtolower('i')대문자가 동일하더라도 false를 반환합니다. 대소 문자를 구분하지 않는 문자열 비교 함수를 원한다면 대문자와 소문자 버전을 비교해야합니다.

if(mb_strtolower($string1) === mb_strtolower($string2)
  || mb_strtoupper($string1) === mb_strtoupper($string2))

https://codepoints.net ( https://dumps.codepoints.net ) 에서 유니 코드 데이터베이스에 대해 쿼리를 실행했으며 소문자를 사용할 때 다른 문자를 찾은 180 개의 코드 포인트를 찾았습니다. 대문자의 소문자, 대문자의 소문자 대문자를 취했을 때 다른 문자를 찾은 8 개의 코드 포인트

그러나 악화 : 사용자가 볼 같은 그래 핀 클러스터, 그것을 인코딩의 여러 가지 방법이있을 수 있습니다 : "A가"로 표현 될 수 Latin Small Letter a with Diaeresis (U+00E4)또는 Latin Small Letter A (U+0061)Combining Diaeresis (U+0308)- 당신은 바이트 수준에서 비교하면, 이것이 사실 반환하지 않습니다!

하지만 이에 대한 해결책은 유니 코드 : 정규화 ! NFC, NFD, NFKC, NFKD의 네 가지 형식이 있습니다. 문자열 비교의 경우 NFC와 NFD는 동일하고 NFKC와 NFKD는 동일합니다. NFKC는 NFKD보다 짧기 때문에 NFKC를 사용하고 "ff"( Latin Small Ligature ff, U+FB00)는 두 개의 일반 "f"로 변환됩니다 (하지만 2⁵도 25로 확장됩니다…).

결과 함수는 다음과 같습니다.

function mb_is_string_equal_ci($string1, $string2) {
    $string1_normalized = Normalizer::normalize($string1, Normalizer::FORM_KC);
    $string2_normalized = Normalizer::normalize($string2, Normalizer::FORM_KC);
    return mb_strtolower($string1_normalized) === mb_strtolower($string2_normalized)
            || mb_strtoupper($string1_normalized) === mb_strtoupper($string2_normalized);
}

참고 :

  • Normalizerintl 패키지 가 필요합니다.
  • 이 기능이 같은지 먼저 확인하여 최적화해야합니다 ^^
  • NFKC는 취향에 따라 너무 많은 서식 구분을 제거하므로 NFKC 대신 NFC를 사용하는 것이 좋습니다.
  • 이 모든 복잡성이 정말로 필요한지 또는이 함수의 더 간단한 변형을 선호하는지 직접 결정해야합니다.

if(strtolower($var1) == strtolower($var2)){
}

strcasecmp를 사용하십시오 .


왜 안 되는가 :

if(strtolower($var1) == strtolower($var2)){
}

참고 URL : https://stackoverflow.com/questions/5473542/case-insensitive-string-comparison

반응형