Подтвердить что ты не робот

Сравнение нечувствительных к регистру строк

Я хотел бы сравнить две переменные, чтобы увидеть, являются ли они одинаковыми, но я хочу, чтобы это сравнение было нечувствительным к регистру.

Например, это будет чувствительным к регистру:

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

Но я хочу, чтобы это было нечувствительным к регистру, как бы я к этому подошел?

4b9b3361

Ответ 1

Это довольно просто; вам просто нужно вызвать strtolower() для обеих переменных.

Если вам нужно иметь дело с Unicode или международными наборами символов, вы можете использовать mb_strtolower().

Обратите внимание, что в других ответах предлагается использовать strcasecmp() — эта функция не обрабатывает многобайтовые символы, поэтому результаты для любой строки UTF-8 будут фиктивными.

Ответ 2

strcasecmp() возвращает 0, если строки одинаковы (кроме вариантов case), поэтому вы можете использовать:

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

Ответ 3

Если ваша строка находится в одной байтовой кодировке, она проста:

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

Если ваша строка UTF-8, вы должны учитывать сложность Unicode: от-нижнего и верхнего - не биективные функции, т.е. если у вас есть строчный символ, преобразуйте его в верхний регистр, и преобразовать его обратно в нижний регистр, вы можете не иметь ту же самую кодовую точку (и то же самое верно, если вы начинаете с символа верхнего регистра).

например.

  • "İ" (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" (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))

Я запустил запрос к базе данных Unicode из https://codepoints.net (https://dumps.codepoints.net), и я нашел 180 пунктов кода, для которых я нашел другой символ, когда делал строчный регистр нижнего регистра, и 8 кодовых точек, для которых я нашел другой символ, когда взятие верхнего регистра символов в верхнем регистре

Но он становится хуже: тот же самый графем-кластер, который видит пользователь, может иметь несколько способов его кодирования: "ä" может быть представлен как Latin Small Letter a with Diaeresis (U+00E4) или как Latin Small Letter A (U+0061) и Combining Diaeresis (U+0308) - и если вы сравните их на уровне байта, это не вернет true!

Но в Unicode есть решение: Нормализация! Существует четыре различных формы: NFC, NFD, NFKC, NFKD. Для сравнения строк NFC и NFD эквивалентны, а NFKC и NFKD эквивалентны. Я бы взял NFKC, поскольку он короче NFKD, а "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);
}

Обратите внимание:

  • вам нужен intl пакет для Normalizer
  • вам следует оптимизировать эту функцию, сначала проверив, насколько они равны ^^
  • вы можете использовать NFC вместо NFKC, потому что NFKC удаляет слишком много различий в форматировании для вашего вкуса.
  • вам нужно решить для себя, если вам действительно нужна вся эта сложность или вы предпочитаете более простой вариант этой функции.

Ответ 4

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

Ответ 6

Почему бы и нет:

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