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

Я пытаюсь получить поиск без учета регистра с двумя рабочими строками в 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 к приведенному выше примеру, он будет искать поисковую строку, а не то, что находится в переменной "searchstring" (следующий пример не работает):

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

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

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
281
0
309 618
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

Ответ принят как подходящий

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

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

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

Использование подобного регулярного выражения, вероятно, самый простой и очевидный способ сделать это в 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');
}

Извините, как в первом примере преобразовать «лучшее» в переменную? string.match(/best/i);

Doug Molineux 23.10.2015 19:00

Зачем вам использовать .match для логического сравнения. Он ищет не только первый результат. Вам нужно остановиться после первого совпадения, которое делает .test или .search. Проверить производительность здесь.

Rami 29.03.2016 01:15

toLowerCase, скорее всего, не пройдет тест Турции (moserware.com/2008/02/does-your-code-pass-turkey-test.html) и аналогичные проблемы с преобразованием регистра. Я не уверен, как ReGex справляется с этим, но если бы мне пришлось угадывать, я бы сказал лучше.

Ohad Schneider 11.07.2016 14:37

@DougMolineux вы можете использовать конструктор объекта RegExp. var text = "best"; var exp = new RegExp(test, "i");. Это то же самое, что и /best/i.

Medeni Baykal 14.01.2019 12:20

Заменять

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

с

var result= string.search(new RegExp(searchstring, "i"));

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

Dan 07.10.2008 14:42

Дэн, я сомневаюсь, что мой ответ заслуживает от тебя -1. Я попытался помочь Крису Бо, исправив его неправильное использование JavaScript, а именно: var result = string.search (/ searchstring / i); на правильный, где переменная строка поиска использовалась так, как он задумал.

Sergey Ilinsky 07.10.2008 14:51

Дэн прав (хотя он, вероятно, имел в виду «меры нет»): s = 'a[b'; r = new RegExp(s) приводит к синтаксической ошибке (незавершенный класс символов)

glenn jackman 26.01.2010 20:47

Если вы просто ищете строку, а не более сложное регулярное выражение, вы можете использовать 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;

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

searchstring = searchstring.replace(/[^a-zA-Z 0-9]+/g,'');

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

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.info('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 );

            }
        } 

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

  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>
    

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

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

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

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

var haystack = 'A. BAIL. Of. Hay.';
var needle = 'bail.';
var index = haystack.naturalIndexOf(needle);

ES6 +:

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


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

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

Я делаю это довольно часто и использую простой 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.info('Searching for', item)
  result = content.containsIgnoreCase(item)
  console.info(result ? 'Found' : 'Not Found')
})

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

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

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

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

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

Другие вопросы по теме