strcasecmp — Сравнение строк без учета регистра, безопасное для данных в двоичной форме


FPublisher

Web-технологии: База знаний

Документация PHP

strcasecmp

strcasecmp — Сравнение строк без учета регистра, безопасное для данных в двоичной форме

Описание

int strcasecmp ( string $str1 , string $str2 )

Возвращает отрицательное число, если str1 меньше, чем str2 ; положительное число, если str1 больше, чем str2 , и 0 если строки равны.

Пример #1 Пример использования strcasecmp()

= «Hello» ;
$var2 = «hello» ;
if ( strcasecmp ( $var1 , $var2 ) == 0 ) <
echo ‘$var1 равно $var2 при сравнении без учета регистра’ ;
>
?>

strcasecmp

(PHP 4, PHP 5, PHP 7)

strcasecmp — Бинарно-безопасное сравнение строк без учета регистра

Описание

Бинарно-безопасное сравнение строк без учета регистра.

Список параметров

Возвращаемые значения

Возвращает отрицательное число, если str1 меньше str2 , положительное число, если str1 больше str2 , и 0, если строки равны.

Примеры

Пример #1 Пример использования strcasecmp()

Смотрите также

  • strcmp() — Бинарно-безопасное сравнение строк
  • preg_match() — Выполняет проверку на соответствие регулярному выражению
  • substr_compare() — Бинарно-безопасное сравнение 2 строк со смещением, с учетом или без учета регистра
  • strncasecmp() — Бинарно-безопасное сравнение первых n символов строк без учета регистра
  • stristr() — Регистронезависимый вариант функции strstr
  • substr() — Возвращает подстроку

strcmpi

сравнение символьных строк (без учёта регистра)

Последовательность вызова

Аргументы

символьная строка или матрица символьных строк.

символьная строка или матрица символьных строк.

матрица целочисленных значений.

Описание


res = strcmpi ( string_one , string_two ) возвращает интегральное значение, указывающее отношение между строками.

Значение равно 0 , если string_one равна string_two (независимо от регистра), а 1 указывает обратное.

Сравнение строк без учета регистра

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

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

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

6 ответов

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

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

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

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

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

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

  • «İ» ( Latin Capital Letter I with Dot Above, U+0130 ) — это символ верхнего регистра, с «i» ( Latin Small Letter I, U+0069 ) в качестве варианта нижнего регистра — и «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, даже если они имеют одинаковый символ верхнего регистра. Если вы действительно хотите использовать функцию сравнения строк без учета регистра, вы должны сравнить ее с заглавной и строчной версиями:

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

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

Илон Маск рекомендует:  Что такое код ncurses_nonl

Но в Unicode есть решение для этого: нормализация ! Существует четыре различных формы: NFC, NFD, NFKC, NFKD. Для сравнения строк NFC и NFD эквивалентны, а NFKC и NFKD эквивалентны. Я бы взял NFKC, так как он короче, чем NFKD, и «ff» ( Latin Small Ligature ff, U+FB00 ) будет преобразовано в два нормальных «f» (но 2⁵ также будет увеличено до 25…).

Результирующая функция становится:

Пожалуйста, обратите внимание:

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

Сравнение строк без учета регистра символов

Сравнение строк без учета регистра символов

Если вам когда-либо доводилось писать программы, в которых используются строки (а кому, спрашивается, не доводилось?), скорее всего, вы встречались с типичной ситуацией — две строки, различающиеся только регистром символов, должны были интерпретироваться как равные. В этих случаях требовалось, чтобы операции сравнения — проверка равенства, больше-меньше, выделение подстрок, сортировка — игнорировали регистр символов. Программисты очень часто спрашивают, как организовать подобные операции средствами стандартной библиотеки С++. На этот вопрос существует огромное количество ответов, многие из которых неверны.

Прежде всего необходимо избавиться от мысли о написании класса, сравнивающего строки без учета регистра. Да, с технической точки зрения это более или менее возможно. Тип std:: string стандартной библиотеки в действительности является синонимом для типа std::basic_string ,sd:: allocator >. Операции сравнения определяются вторым параметром; передавая второй параметр с переопределенными операциями «равно» и «меньше», можно специализировать basic_string таким образом, что операции >). Параметры характеристик (traits) должны совпадать. Если вы используете строки типа std:: basic_string , то для вывода строк должен использоваться тип std::basic_ostream . Стандартные потоки cin и cout для этой цели не подойдут.

Игнорирование регистра символов является не свойством объекта, а лишь контекстом его использования. Вполне возможно, что в одном контексте строки должны интерпретироваться с учетом регистра, а в другом контексте регистр должен игнорироваться (например, при установке соответствующего режима пользователем).

Решение не соответствует канонам. Класс char_traits, как и все классы характеристик[5], прост, компактен и не содержит информации состояния. Как будет показано ниже, правильная реализация сравнений без учета регистра не отвечает ни одному из этих критериев.

Этого вообще не достаточно. Даже если все функции basic_string будут игнорировать регистр, это никак не отразится на использовании внешних обобщенных алгоритмов, таких как std::search и std::find_end. Кроме того, такое решение перестает работать, если по соображениям эффективности перейти от контейнера объектов basicstring к таблице строк.


Более правильное решение, которое лучше соответствует архитектуре стандартной библиотеки, заключается в том, чтобы игнорировать регистр символов только в тех случаях, когда это действительно необходимо. Не стоит возиться с такими функциями контейнера string, как string::find_first или string::rfind; они лишь дублируют функциональные возможности, уже поддерживаемые внешними обобщенными алгоритмами. С другой стороны, алгоритмы обладают достаточной гибкостью, что позволяет реализовать в них поддержку сравнений строк без учета регистра. Например, чтобы отсортировать коллекцию строк без учета регистра, достаточно передать алгоритму працильный объект функции сравнения:

std::sort(С.begin(), С.end().compare_wi thout_case);

Написанию таких объектов и посвящена эта статья.

Сравнение строк без учета регистра в C ++ [закрыто]

Каков наилучший способ сравнения строк без учета регистра в C ++ без преобразования строки в верхний или нижний регистр?

Укажите, являются ли методы дружественными к Юникоду и насколько они переносимы. [110] 111]

31 ответ

Повышение включает удобный алгоритм для этого:

это, вероятно, можно сделать гораздо более эффективным, но вот громоздкая версия со всеми ее битами.

не такой портативный, но хорошо работает с тем, что есть на моем компьютере (не знаю, я из картинок, а не слов)

Простой способ сравнить две строки в c ++ (проверено для windows) — использовать _stricmp

Если вы хотите использовать с std :: string, пример:

Если вам приходится сравнивать исходную строку чаще с другими строками, одним из элегантных решений является использование регулярных выражений.

Если у вас есть вектор строк, например:

Если вы не хотите использовать Boost-библиотеку , то здесь есть решение, использующее только стандартный C ++ заголовок io.

В начале 2013 года проект ICU, поддерживаемый IBM, является довольно хорошим ответом на это.

ICU — это «полная, портативная библиотека Unicode, которая близко отслеживает отраслевые стандарты». Для конкретной задачи сравнения строк объект Collation делает то, что вы хотите.

Проект Mozilla принял ICU для интернационализации в Firefox в середине 2012 года; обсуждение технических вопросов, включая вопросы о системах сборки и размере файла данных, можно найти здесь:

Илон Маск рекомендует:  Форматирование текста

Поздно к вечеринке, но вот вариант, который использует std::locale и, следовательно, правильно обрабатывает турецкий язык:

дает вам функтор, который использует активную локаль для преобразования символов в строчные, затем вы можете использовать std::transform для генерации строчных букв:

Это также работает для строк на основе wchar_t .

Простой способ сравнения строк, которые различаются только строчными и заглавными буквами, состоит в сравнении ascii. Все прописные и строчные буквы различаются на 32 бита в таблице ASCII, используя эту информацию, мы имеем следующее .

У меня был хороший опыт использования Международных Компонентов для библиотек Unicode — они чрезвычайно мощные и предоставляют методы для преобразования, поддержки локали, рендеринга даты и времени, отображения дел (что вам не нужно t, кажется, хотят), и сопоставление , которое включает сравнение без учета регистра и акцента (и многое другое). Я использовал только версию библиотек на C ++, но, похоже, они также имеют версию Java.

Существуют методы для выполнения нормализованного сравнения, на которые ссылается @Coincoin, и они могут даже учитывать локаль — например (и это пример сортировки, а не строго равенство), традиционно на испанском (в Испании) буква комбинация «ll» сортирует между «l» и «m», поэтому «lz»

Похоже, что вышеупомянутые решения не используют метод сравнения и снова реализуют итоги, так что вот мое решение и надеюсь, что оно работает для вас (работает нормально).

Для этого без использования Boost можно получить указатель на строку C с помощью c_str() и использовать strcasecmp :

Просто используйте strcmp() для чувствительности к регистру и strcmpi() или stricmp() для сравнения без учета регистра. Оба из которых находятся в заголовочном файле

формат:

Использование:

Выходные данные


apple и ApPlE одинаковы

a предшествует b, поэтому apple предшествует мячу

Просто обратите внимание на то, какой метод вы в конечном итоге выберете, если этот метод включает в себя использование strcmp , которое предлагают некоторые ответы:

strcmp не работает с данными Unicode в целом. В целом, он даже не работает с байтовыми кодировками Unicode, такими как utf-8, поскольку strcmp выполняет только байтовое сравнение, а кодовые точки Unicode, закодированные в utf-8, могут занимать более 1 байта. Единственный конкретный случай Unicode strcmp , который правильно обрабатывается, — это когда строка, закодированная с помощью байтовой кодировки, содержит только кодовые точки ниже U + 00FF — тогда достаточно сравнения байтов на байты.

Вы можете использовать приведенный выше код на C ++ 14, если вы не в состоянии использовать boost. Вы должны использовать std::towlower для широких символов.

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

В противном случае большое количество исторических реализаций библиотеки C имеет функции stricmp () и strnicmp (). Visual C ++ в Windows переименовал все это, поставив перед ними префикс подчеркивания, потому что они не являются частью стандарта ANSI, поэтому в этой системе их называют _stricmp или _strnicmp . Некоторые библиотеки могут также иметь широко-символьные или многобайтовые эквивалентные функции (обычно называемые, например, wcsicmp, mbcsicmp и т. Д.).

C и C ++ в значительной степени не знают о проблемах интернационализации, поэтому у этой проблемы нет иного решения, кроме как использовать стороннюю библиотеку. Проверьте IBM ICU (Международные компоненты для Unicode) , если вам нужна надежная библиотека для C / C ++. ICU для систем Windows и Unix.

Strcasecmp — Сравнение строк без учета регистра, безопасное для данных в двоичной форме

(PHP 3 >= 3.0.2, PHP 4, PHP 5)

strcasecmp — Сравнение строк без учета регистра, безопасное для данных в двоичной форме

Описание int strcasecmp ( string str1, string str2 )

Возвращает отрицательное число, если str1 меньше, чем str2 ; положительное число, если str1 больше, чем str2 , и 0 если строки равны.

Пример 1. Пример использования strcasecmp()

strcmpi

сравнение символьных строк (без учёта регистра)

Последовательность вызова

Аргументы

символьная строка или матрица символьных строк.

символьная строка или матрица символьных строк.

матрица целочисленных значений.

Описание

res = strcmpi ( string_one , string_two ) возвращает интегральное значение, указывающее отношение между строками.

Значение равно 0 , если string_one равна string_two (независимо от регистра), а 1 указывает обратное.

Strcasecmp

Php функции


Php скрипты


strcasecmp

(PHP 3 >= 3.0.2, PHP 4, PHP 5)

strcasecmp — Сравнение строк без учета регистра, безопасное для данных в двоичной форме


Описание

int strcasecmp ( string str1, string str2 )

Возвращает отрицательное число, если str1 меньше, чем str2 ; положительное число, если str1 больше, чем str2 , и 0 если строки равны.

Пример 1. Пример использования strcasecmp()

$var1 = «Hello» ;
$var2 = «hello» ;
if ( strcasecmp ( $var1 , $var2 ) == 0 ) <
echo ‘ $var1 равно $var2 при сравнении без учета регистра’ ;
>
?>

User Contributed Notes

The sample above is only true on some platforms that only use a simple ‘C’ locale, where individual bytes are considered as complete characters that are converted to lowercase before being differentiated.

Other locales (see LC_COLLATE and LC_ALL) use the difference of collation order of characters, where characters may be groups of bytes taken from the input strings, or simply return -1, 0, or 1 as the collation order is not simply defined by comparing individual characters but by more complex rules.

Don’t base your code on a specific non null value returned by strcmp () or strcasecmp (): it is not portable. Just consider the sign of the result and be sure to use the correct locale!

Сравнение строк без учета регистра

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

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

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

6 ответов

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

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

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

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

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

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

  • «İ» ( Latin Capital Letter I with Dot Above, U+0130 ) — это символ верхнего регистра, с «i» ( Latin Small Letter I, U+0069 ) в качестве варианта нижнего регистра — и «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, даже если они имеют одинаковый символ верхнего регистра. Если вы действительно хотите использовать функцию сравнения строк без учета регистра, вы должны сравнить ее с заглавной и строчной версиями:

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

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

Но в Unicode есть решение для этого: нормализация ! Существует четыре различных формы: NFC, NFD, NFKC, NFKD. Для сравнения строк NFC и NFD эквивалентны, а NFKC и NFKD эквивалентны. Я бы взял NFKC, так как он короче, чем NFKD, и «ff» ( Latin Small Ligature ff, U+FB00 ) будет преобразовано в два нормальных «f» (но 2⁵ также будет увеличено до 25…).

Результирующая функция становится:

Пожалуйста, обратите внимание:

  • вам нужен пакет intl для нормализатора
  • Вы должны оптимизировать эту функцию, сначала проверив, равны ли они ^^
  • вы можете использовать NFC вместо NFKC, потому что NFKC удаляет слишком много различий в форматировании на ваш вкус
  • Вы должны решить для себя, действительно ли вам нужна вся эта сложность или вы предпочитаете более простой вариант этой функции
Илон Маск рекомендует:  HTTP - заголовки
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL