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

272

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

Обычно это будет так:

var string="Stackoverflow is the BEST";
var result= string.search(/best/i);
alert(result);

/iФлаг будет для регистра.

Но мне нужно искать вторую строку; без флага работает отлично

var string="Stackoverflow is the BEST";
var searchstring="best";
var result= string.search(searchstring);
alert(result);

Если я добавлю /iфлаг в приведенный выше пример, он будет искать строку поиска, а не то, что находится в переменной «строка поиска» (следующий пример не работает):

var string="Stackoverflow is the BEST";
var searchstring="best";
var result= string.search(/searchstring/i);
alert(result);

Как мне этого добиться?

Крис Боинг
источник

Ответы:

373

Да, используйте .match, а не .search. Результат от .matchвызова вернет фактическую строку, которая была сопоставлена ​​сама, но она все еще может использоваться как логическое значение.

var string = "Stackoverflow is the BEST";
var result = string.match(/best/i);
// result == 'BEST';

if (result){
    alert('Matched');
}

Используя регулярное выражение , как это, вероятно, tidiest и самый очевидный способ сделать это в JavaScript, но имейте в виду , что это регулярное выражение, и , таким образом , может содержать регулярное выражение метасимволы. Если вы хотите взять строку из другого места (например, из пользовательского ввода), или если вы хотите избежать экранирования большого количества метасимволов, то вам, вероятно, лучше использовать indexOfследующее:

matchString = 'best';
// If the match string is coming from user input you could do
// matchString = userInput.toLowerCase() here.

if (string.toLowerCase().indexOf(matchString) != -1){
    alert('Matched');
}
Дэн
источник
9
Извините, как вы можете преобразовать «лучший» в переменную в первом примере? string.match(/best/i);
Даг Молинью
5
Почему вы используете .matchдля логического сравнения. Он ищет за пределами первого результата. Вы должны остановиться после первого матча, который .testили .searchделать. Проверьте производительность здесь .
Рами
toLowerCaseскорее всего, не пройдёт тест Турции ( moserware.com/2008/02/does-your-code-pass-turkey-test.html ) и подобные проблемы с конверсией. Я не уверен, как ReGexсправится с этим, но если бы мне пришлось угадывать, я бы сказал лучше.
Охад Шнайдер
3
@DougMolineux вы можете использовать конструктор объекта RegExp. var text = "best"; var exp = new RegExp(test, "i");, Это так же, как /best/i.
Медени Байкал
174

замещать

var result= string.search(/searchstring/i);

с участием

var result= string.search(new RegExp(searchstring, "i"));
Сергей Ильинский
источник
7
Это довольно запутанный способ, так как нужно принимать меры для защиты от неожиданных метасимволов регулярных выражений.
Дан
35
Дэн, я сомневаюсь, что мой ответ заслуживает -1 от тебя. Я попытался помочь ChrisBo, исправив его неправильное использование JavaScript, а именно: var result = string.search (/ searchstring / i); к правильному, где переменная строка поиска использовалась так, как он намеревался.
Сергей Ильинский
8
Дэн прав (хотя он, вероятно, хотел сказать « никаких мер»): s = 'a[b'; r = new RegExp(s)приводит к синтаксической ошибке (неопределенный класс символов)
Гленн Джекман
39

Если вы просто ищете строку, а не более сложное регулярное выражение, вы можете использовать indexOf()- но не забудьте сначала сделать строчные буквы для обеих строк, потому что они indexOf()чувствительны к регистру:

var string="Stackoverflow is the BEST"; 
var searchstring="best";

// lowercase both strings
var lcString=string.toLowerCase();
var lcSearchString=searchstring.toLowerCase();

var result = lcString.indexOf(lcSearchString)>=0;
alert(result);

Или в одной строке:

var result = string.toLowerCase().indexOf(searchstring.toLowerCase())>=0;
Одилон Редо
источник
24

Предположим, мы хотим найти строковую переменную 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);
alert(result);
Крис Шут
источник
4

ES6 +:

let string="Stackoverflow is the BEST";
let searchstring="best";


let found = string.toLowerCase()
                  .includes(searchstring.toLowerCase());

includes()возвращает, trueесли searchStringпоявляется в одной или нескольких позициях или falseиным образом.

Андрей
источник
2

Если вас беспокоит случай «неопределенного класса символов», было бы полезно удалить все не алфавитно-цифровые символы:

searchstring = searchstring.replace (/ [^ a-zA-Z 0-9] + / g, '');
dsomnus
источник
2

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

Тем не менее, это все еще довольно неуклюже, и, возможно, относительно медленнее. Так почему бы не найти конкретное решение того, что обычно является общим требованием для кодировщиков? (А почему бы не включить его в ES6 API?)

Мой ответ [ https://stackoverflow.com/a/38290557/887092] на похожий вопрос позволяет следующее:

var haystack = 'A. BAIL. Of. Hay.';
var needle = 'bail.';
var index = haystack.naturalIndexOf(needle);
Тодд
источник
1

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

  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>
Сохаил Ариф
источник
1

Я делаю это часто и использую простой 5-строчный прототип, который принимает varargs. Это быстро и работает везде .

myString.containsIgnoreCase('red','orange','yellow')

/**
 * @param {...string} var_strings Strings to search for
 * @return {boolean} true if ANY of the arguments is contained in the string
 */
String.prototype.containsIgnoreCase = function(var_strings) {
  const thisLowerCase = this.toLowerCase()
  for (let i = 0; i < arguments.length; i++) {
    let needle = arguments[i]
    if (thisLowerCase.indexOf(needle.toLowerCase()) >= 0) {
      return true
    }
  }
  return false
}

/**
 * @param {...string} var_strings Strings to search for
 * @return {boolean} true if ALL of the arguments are contained in the string
 */
String.prototype.containsAllIgnoreCase = function(var_strings) {
  const thisLowerCase = this.toLowerCase()
  for (let i = 0; i < arguments.length; i++) {
    let needle = arguments[i]
    if (thisLowerCase.indexOf(needle.toLowerCase()) === -1) {
      return false
    }
  }
  return true
}

// Unit test

let content = `
FIRST SECOND
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
FOO BAR
`

let data = [
  'foo',
  'Foo',
  'foobar',
  'barfoo',
  'first',
  'second'
]

let result
data.forEach(item => {
  console.log('Searching for', item)
  result = content.containsIgnoreCase(item)
  console.log(result ? 'Found' : 'Not Found')
})

console.log('Searching for', 'x, y, foo')
result = content.containsIgnoreCase('x', 'y', 'foo');
console.log(result ? 'Found' : 'Not Found')

console.log('Searching for all', 'foo, bar, foobar')
result = content.containsAllIgnoreCase('foo', 'bar', 'foobar');
console.log(result ? 'Found' : 'Not Found')

console.log('Searching for all', 'foo, bar')
result = content.containsAllIgnoreCase('foo', 'bar');
console.log(result ? 'Found' : 'Not Found')

Стивен Спунгин
источник
0

Вы можете сделать все строчными:

var string="Stackoverflow is the BEST";
var searchstring="best";
var result= (string.toLowerCase()).search((searchstring.toLowerCase()));
alert(result);
Robbert
источник
-1

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

var $local_source = [{
        value: 1,
        label: "c++"
    }, {
        value: 2,
        label: "java"
    }, {
        value: 3,
        label: "php"
    }, {
        value: 4,
        label: "coldfusion"
    }, {
        value: 5,
        label: "javascript"
    }, {
        value: 6,
        label: "asp"
    }, {
        value: 7,
        label: "ruby"
    }];
    $('#search-fld').autocomplete({
        source: $local_source,
        select: function (event, ui) {
            $("#search-fld").val(ui.item.label); // display the selected text
            $("#search-fldID").val(ui.item.value); // save selected id to hidden input
            return false;
        },
        change: function( event, ui ) {

            var isInArray = false;

            $local_source.forEach(function(element, index){

                if ($("#search-fld").val().toUpperCase() == element.label.toUpperCase()) {
                    isInArray = true;
                    $("#search-fld").val(element.label); // display the selected text
                    $("#search-fldID").val(element.value); // save selected id to hidden input
                    console.log('inarray: '+isInArray+' label: '+element.label+' value: '+element.value);
                };

            });

            if(!isInArray){

                $("#search-fld").val(''); // display the selected text
                $( "#search-fldID" ).val( ui.item? ui.item.value : 0 );

            }
        } 
Тому назад
источник