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

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

Ответ 1

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

var areEqual = string1.toUpperCase() === string2.toUpperCase();

Ответ 2

РЕДАКТИРОВАТЬ: Этот ответ был первоначально добавлен 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'));

Ответ 3

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

(/keyword/i).test(source)

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

(/keyword/).test(source)

Ответ 4

Помните, что корпус - это специфическая для локали операция. В зависимости от сценария вы можете принять это за счет. Например, если вы сравниваете имена двух человек, вы можете захотеть рассмотреть локаль, но если вы сравниваете машинные сгенерированные значения, такие как 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;
}

Ответ 5

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

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

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

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

function equalsIgnoringCase(text, other) {
    return 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 для получения актуальной информации.

Ответ 6

Недавно я создал микробиблиотеку, в которой есть помощники для строк без учета регистра: 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

если вас беспокоит направление неравенства (возможно, вы хотите отсортировать список) вам довольно-таки нужно делать case-преобразование, и поскольку в юникоде есть более строчные символы, чем верхний регистр 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. там не так много, что можно сделать по этому поводу, не делая более подробного осмотра строк.

Ответ 8

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

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

Ответ 9

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

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

Используйте метод строки поиска для поиска без учета регистра. Читайте о методах поиска и других строках в: 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>

Ответ 10

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

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");
}

Ответ 11

str = 'Lol', str2 = 'lOl', regex = new RegExp('^' + str + '$', 'i');
if (regex.test(str)) {
    console.log("true");
}

Ответ 12

Если обе строки имеют одну и ту же известную локаль, вы можете использовать объект Intl.Collator например:

function equalIgnoreCase(s1: string, s2: string) {
    return new Intl.Collator("en-US", { sensitivity: "base" }).compare(s1, s2) === 0;
}

Очевидно, вы можете кэшировать Collator для повышения эффективности.

Преимущества этого подхода в том, что он должен быть намного быстрее, чем использование RegExps, и основан на чрезвычайно настраиваемом (см. Описание options конструктора locales и параметров в статье выше) готовом к использованию сборщике.

Ответ 13

Я написал расширение. очень тривиально

if (typeof String.prototype.isEqual!= 'function') {
    String.prototype.isEqual = function (str){
        return this.toUpperCase()==str.toUpperCase();
     };
}

Ответ 14

Даже этот вопрос уже ответил. У меня есть другой подход к использованию RegExp и совпадение, чтобы игнорировать регистр. См. Мою ссылку https://jsfiddle.net/marchdave/7v8bd7dq/27/

$("#btnGuess").click(guessWord);

  function guessWord() {

   var letter = $("#guessLetter").val();
   var word = 'ABC';
   var pattern = RegExp(letter, 'gi'); // pattern: /a/gi

   var result = word.match(pattern);
   alert('Ignore case sensitive:' + result);

  }

Ответ 15

Используйте RegEx для совпадения строк или сравнения.

В JavaScript вы можете использовать match() для сравнения строк, не забудьте поместить i в RegEx.

Пример:

var matchString = "Test";
if (matchString.match(/test/i)) {
  alert('String matched');
}
else {
 alert('String not matched');
}

Ответ 16

Как насчет NOT бросать исключения и НЕ использовать медленное регулярное выражение?

return str1 != null && str2 != null 
    && typeof str1 === 'string' && typeof str2 === 'string'
    && str1.toUpperCase() === str2.toUpperCase();

В приведенном выше фрагменте предполагается, что вы не хотите сопоставлять, если строка равна null или undefined.

Если вы хотите совместить null/ undefined, то:

return (str1 == null && str2 == null)
    || (str1 != null && str2 != null 
        && typeof str1 === 'string' && typeof str2 === 'string'
        && str1.toUpperCase() === str2.toUpperCase());

Если по какой-то причине вы заботитесь о undefined vs null:

return (str1 === undefined && str2 === undefined)
    || (str1 === null && str2 === null)
    || (str1 != null && str2 != null 
        && typeof str1 === 'string' && typeof str2 === 'string'
        && str1.toUpperCase() === str2.toUpperCase());

Ответ 17

Поскольку никакой ответ явно не предоставил простой фрагмент кода для использования RegExp, здесь моя попытка:

function compareInsensitive(str1, str2){ 
  return typeof str1 === 'string' && 
    typeof str2 === 'string' && 
    new RegExp("^" + str1.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + "$", "i").test(str2);
}

Он имеет несколько преимуществ:

  • Проверяет тип параметра (например, любой нестроковый параметр, например undefined, вырвал бы выражение, подобное str1.toUpperCase()).
  • Не страдает от возможных проблем интернационализации.
  • Сбрасывает строку RegExp.

Ответ 18

Это улучшенная версия этого ответа.

String.equal = function (s1, s2, ignoreCase, useLocale) {
    if (s1 == null || s2 == null)
        return false;

    if (!ignoreCase) {
        if (s1.length !== s2.length)
            return false;

        return s1 === s2;
    }

    if (useLocale) {
        if (useLocale.length)
            return s1.toLocaleLowerCase(useLocale) === s2.toLocaleLowerCase(useLocale)
        else
            return s1.toLocaleLowerCase() === s2.toLocaleLowerCase()
    }
    else {
        if (s1.length !== s2.length)
            return false;

        return s1.toLowerCase() === s2.toLowerCase();
    }
}



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

String.equal = function (s1, s2, ignoreCase, useLocale) {
    if (s1 == null || s2 == null)
        return false;

    if (!ignoreCase) {
        if (s1.length !== s2.length)
            return false;

        return s1 === s2;
    }

    if (useLocale) {
        if (useLocale.length)
            return s1.toLocaleLowerCase(useLocale) === s2.toLocaleLowerCase(useLocale)
        else
            return s1.toLocaleLowerCase() === s2.toLocaleLowerCase()
    }
    else {
        if (s1.length !== s2.length)
            return false;

        return s1.toLowerCase() === s2.toLowerCase();
    }
}

// If you don't mind extending the prototype.
String.prototype.equal = function(string2, ignoreCase, useLocale) {
  return String.equal(this.valueOf(), string2, ignoreCase, useLocale);
}

// ------------------ TESTS ----------------------
console.log("Tests...");

console.log('Case sensitive 1');
var result = "Abc123".equal("Abc123");
console.assert(result === true);

console.log('Case sensitive 2');
result = "aBC123".equal("Abc123");
console.assert(result === false);

console.log('Ignore case');
result = "AbC123".equal("aBc123", true);
console.assert(result === true);

console.log('Ignore case + Current locale');
result = "AbC123".equal("aBc123", true);
console.assert(result === true);

console.log('Turkish test 1 (ignore case, en-US)');
result = "IiiI".equal("ıiİI", true, "en-US");
console.assert(result === false);

console.log('Turkish test 2 (ignore case, tr-TR)');
result = "IiiI".equal("ıiİI", true, "tr-TR");
console.assert(result === true);

console.log('Turkish test 3 (case sensitive, tr-TR)');
result = "IiiI".equal("ıiİI", false, "tr-TR");
console.assert(result === false);

console.log('null-test-1');
result = "AAA".equal(null);
console.assert(result === false);

console.log('null-test-2');
result = String.equal(null, "BBB");
console.assert(result === false);

console.log('null-test-3');
result = String.equal(null, null);
console.assert(result === false);

Ответ 19

Преобразуйте оба в нижний (только один раз по соображениям производительности) и сравните их с троичным оператором в одну строку:

function strcasecmp(s1,s2){
    s1=(s1+'').toLowerCase();
    s2=(s2+'').toLowerCase();
    return s1>s2?1:(s1<s2?-1:0);
}