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

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

17 ответов


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

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

редактировать: этому ответу 7 лет. Сегодня вы должны использовать localeCompare.

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

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

JavaScript: поиск без учета регистра

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

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

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


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

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

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

(/keyword/i).test(source)

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

(/keyword/).test(source)

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

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

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


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

Предположим, мы хотим найти переменную строку 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
}

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

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

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

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

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

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

в Швеции, ä и отдельные базы письма!--7-->

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

Sensitivity options tabulated from MDN

поддержка браузеров

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


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

  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>

здесь много ответов, но мне нравится добавлять sollution на основе расширения строки 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");
}

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

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

  }

используйте regix для сопоставления строк или сравнения ,

в javaScript вы можете использовать match() для сравнения строк , не забудьте поставить меня в regix

пример :

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

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

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());

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

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

Он имеет ряд преимуществ:

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

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

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

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

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


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

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