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

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

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

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

Ответ 1

Да, используйте .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');
}

Ответ 2

Заменить

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

с

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

Ответ 3

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

Ответ 4

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

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

Ответ 5

ES6+:

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


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

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

Ответ 6

Если вас беспокоит случай "unterminated character class", было бы полезно удалить все небуквенные символы:

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

Ответ 7

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

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

Мой ответ [fooobar.com/questions/13496/... по аналогичному вопросу позволяет следующее:

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

Ответ 8

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

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

Ответ 9

Я делаю это часто и использую простой 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')

Ответ 10

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

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

Ответ 11

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

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

            }
        }