Сравнение строк без учета регистра в JavaScript - PullRequest
899 голосов
/ 26 января 2010

Как выполнить сравнение строк без учета регистра в JavaScript?

Ответы [ 19 ]

1016 голосов
/ 26 января 2010

Самый простой способ сделать это (если вас не волнуют специальные символы Юникода) - позвонить toUpperCase:

var areEqual = string1.toUpperCase() === string2.toUpperCase();
152 голосов
/ 26 января 2010

РЕДАКТИРОВАТЬ : Этот ответ был первоначально добавлен 9 лет назад. Сегодня вы должны использовать localeCompare с опцией sensitivity: 'accent':

function ciEquals(a, b) {
    return typeof a === 'string' && typeof b === 'string'
        ? a.localeCompare(b, undefined, { sensitivity: 'accent' }) === 0
        : a === b;
}

console.log("'a' = 'a'?", ciEquals('a', 'a'));
console.log("'AaA' = 'aAa'?", ciEquals('AaA', 'aAa'));
console.log("'a' = 'á'?", ciEquals('a', 'á'));
console.log("'a' = 'b'?", ciEquals('a', 'b'));

{ sensitivity: 'accent' } говорит localeCompare() обрабатывать два варианта одной и той же базовой буквы как один и тот же , если только они не имеют разные акценты (как в третьем примере) выше.

Кроме того, вы можете использовать { sensitivity: 'base' }, который обрабатывает два символа как эквивалентные, если их базовый символ одинаков (поэтому A будет рассматриваться как эквивалентный á).

Обратите внимание , что третий параметр localeCompare не поддерживается в IE10 или более ранних версиях или в некоторых мобильных браузерах (см. Таблицу совместимости на странице, указанной выше), поэтому если вам необходимо поддерживать эти браузеры, вам понадобится некоторый запасной вариант:

function ciEqualsInner(a, b) {
    return a.localeCompare(b, undefined, { sensitivity: 'accent' }) === 0;
}

function ciEquals(a, b) {
    if (typeof a !== 'string' || typeof b !== 'string') {
        return a === b;
    }

    //      v--- feature detection
    return ciEqualsInner('A', 'a')
        ? ciEqualsInner(a, b)
        : /*  fallback approach here  */;
}

Оригинальный ответ

Лучший способ сделать сравнение без учета регистра в JavaScript - это использовать метод RegExp match() с флагом i.

Поиск без учета регистра

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

Если вы заботитесь о интернационализации, не используйте toLowerCase() или toUpperCase(), поскольку она не обеспечивает точного сравнения без учета регистра на всех языках.

http://www.i18nguy.com/unicode/turkish-i18n.html

32 голосов
/ 24 сентября 2013

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

(/keyword/i).test(source)

/i для случая игнорирования. Если в этом нет необходимости, мы можем проигнорировать и проверить на НЕ совпадение с учетом регистра, например

(/keyword/).test(source)
26 голосов
/ 02 декабря 2013

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

function compareStrings (string1, string2, ignoreCase, useLocale) {
    if (ignoreCase) {
        if (useLocale) {
            string1 = string1.toLocaleLowerCase();
            string2 = string2.toLocaleLowerCase();
        }
        else {
            string1 = string1.toLowerCase();
            string2 = string2.toLowerCase();
        }
    }

    return string1 === string2;
}
15 голосов
/ 24 июня 2018

Как говорилось в последних комментариях, string::localCompare поддерживает сравнение без учета регистра (среди других важных вещей).

Вот простой пример

'xyz'.localeCompare('XyZ', undefined, { sensitivity: 'base' }); // returns 0

И универсальная функция, которую вы можете использовать

function equalsIgnoringCase(text, other) {
    text.localeCompare(other, undefined, { sensitivity: 'base' }) === 0;
}

Обратите внимание, что вместо undefined вам, вероятно, следует ввести конкретную локаль, с которой вы работаете. Это важно, как указано в MDN документах

на шведском, ä и a - отдельные базовые буквы

Параметры чувствительности

Sensitivity options tabulated from MDN

Поддержка браузера

На момент публикации UC Browser для Android и Opera Mini не поддерживает локаль и параметры . Пожалуйста, проверьте https://caniuse.com/#search=localeCompare для получения актуальной информации.

11 голосов
/ 06 августа 2014

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

function my_strcasecmp( a, b ) 
{
    if((a+'').toLowerCase() > (b+'').toLowerCase()) return 1  
    if((a+'').toLowerCase() < (b+'').toLowerCase()) return -1
    return 0
}

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

11 голосов
/ 04 мая 2016

Недавно я создал микробиблиотеку, которая предоставляет регистр-независимые помощники строк: https://github.com/nickuraltsev/ignore-case. (внутри него используется toUpperCase).

var ignoreCase = require('ignore-case');

ignoreCase.equals('FOO', 'Foo'); // => true
ignoreCase.startsWith('foobar', 'FOO'); // => true
ignoreCase.endsWith('foobar', 'BaR'); // => true
ignoreCase.includes('AbCd', 'c'); // => true
ignoreCase.indexOf('AbCd', 'c'); // => 2
7 голосов
/ 06 июля 2016

Предположим, мы хотим найти строковую переменную needle в строковой переменной haystack. Есть три ошибки:

  1. В интернационализированных приложениях следует избегать string.toUpperCase и string.toLowerCase. Используйте регулярное выражение, которое игнорирует регистр. Например, var needleRegExp = new RegExp(needle, "i");, за которым следует needleRegExp.test(haystack).
  2. Как правило, вы можете не знать значение needle. Обратите внимание, что needle не содержит регулярных выражений специальных символов . Избавьтесь от них, используя needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");.
  3. В других случаях, если вы хотите точно соответствовать needle и haystack, просто игнорируя регистр, обязательно добавьте "^" в начале и "$" в конце вашего конструктора регулярного выражения. *

Принимая во внимание пункты (1) и (2), пример будет:

var haystack = "A. BAIL. Of. Hay.";
var needle = "bail.";
var needleRegExp = new RegExp(needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), "i");
var result = needleRegExp.test(haystack);
if (result) {
    // Your code here
}
4 голосов
/ 02 августа 2017

Здесь много ответов, но мне нравится добавлять решение, основанное на расширении библиотеки String:

String.prototype.equalIgnoreCase = function(str)
{
    return (str != null 
            && typeof str === 'string'
            && this.toUpperCase() === str.toUpperCase());
}

Таким образом, вы можете использовать его так же, как в Java!

Пример:

var a = "hello";
var b = "HeLLo";
var c = "world";

if (a.equalIgnoreCase(b)) {
    document.write("a == b");
}
if (a.equalIgnoreCase(c)) {
    document.write("a == c");
}
if (!b.equalIgnoreCase(c)) {
    document.write("b != c");
}

Вывод будет:

"a == b"
"b != c"

String.prototype.equalIgnoreCase = function(str) {
  return (str != null &&
    typeof str === 'string' &&
    this.toUpperCase() === str.toUpperCase());
}


var a = "hello";
var b = "HeLLo";
var c = "world";

if (a.equalIgnoreCase(b)) {
  document.write("a == b");
  document.write("<br>");
}
if (a.equalIgnoreCase(c)) {
  document.write("a == c");
}
if (!b.equalIgnoreCase(c)) {
  document.write("b != c");
}
4 голосов
/ 23 июня 2015

Существует два способа сравнения без учета регистра:

  1. Преобразование строк в верхний регистр, а затем сравнение их с помощью оператора строгого (===) Как строгий оператор относится к операндам, прочитанным в: http://www.thesstech.com/javascript/relational-logical-operators
  2. Сопоставление шаблонов с использованием строковых методов:

Используйте строковый метод поиска для поиска без учета регистра. Читайте о поиске и других строковых методах по адресу: http://www.thesstech.com/pattern-matching-using-string-methods

<!doctype html>
  <html>
    <head>
      <script>

        // 1st way

        var a = "apple";
        var b = "APPLE";  
        if (a.toUpperCase() === b.toUpperCase()) {
          alert("equal");
        }

        //2nd way

        var a = " Null and void";
        document.write(a.search(/null/i)); 

      </script>
    </head>
</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...