Пошуковий нечутливий пошук


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

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

Використання подібного регулярного виразу, мабуть, найправильніший і очевидний спосіб зробити це в JavaScript, але майте на увазі, що це регулярний вираз, і таким чином може містити метасимволи regex. Якщо ви хочете взяти рядок з іншого місця (наприклад, введення користувача) або якщо ви не хочете уникати безлічі метахарактерів, вам, мабуть, найкраще користуватися 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);
Doug Molineux

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); до належного, де змінний searchstring використовувався так, як він задумав.
Сергій Ілинський

8
Право Дана (хоча він, мабуть, мав на увазі сказати " ніяких заходів"): s = 'a[b'; r = new RegExp(s)призводить до синтаксичної помилки (невизначений клас символів)
glenn jackman

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

2

Мені подобається відповідь @ CHR15TO, на відміну від інших відповідей, які я бачив на інших подібних запитаннях, ця відповідь насправді показує, як правильно уникнути пошукової рядок, що надається користувачем (а не говорити, що це потрібно, не показуючи, як).

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

Моя відповідь [ 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. Збірка шаблонів за допомогою рядкових методів:

    Використовуйте рядовий метод "search" для нечутливого пошуку регістру. Про методи пошуку та інші рядкові методи читайте на веб-сайті: 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 рядків, який приймає варагги. Це швидко і працює всюди .

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

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

            }
        } 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.