Pesquisa que não diferencia maiúsculas de minúsculas

272

Estou tentando obter uma pesquisa que não diferencia maiúsculas de minúsculas com duas seqüências de caracteres em JavaScript funcionando.

Normalmente, seria assim:

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

A /ibandeira não diferencia maiúsculas de minúsculas.

Mas preciso procurar uma segunda string; sem a bandeira funciona perfeitamente:

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

Se eu adicionar o /isinalizador ao exemplo acima, ele procuraria pela string de pesquisa e não pelo que está na variável "searchstring" (o próximo exemplo não está funcionando):

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

Como posso conseguir isso?

Chris Boesing
fonte

Respostas:

373

Sim, use .match, em vez de .search. O resultado da .matchchamada retornará a sequência real que correspondeu a si mesma, mas ainda pode ser usada como um valor booleano.

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

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

Usar uma expressão regular como essa é provavelmente a maneira mais organizada e óbvia de fazer isso no JavaScript, mas lembre- se de que é uma expressão regular e, portanto, pode conter metacaracteres de expressão regular. Se você quiser pegar a string de outro lugar (por exemplo, entrada do usuário) ou se quiser evitar ter que escapar de muitos metacaracteres, provavelmente é melhor usar o indexOfseguinte:

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');
}
Dan
fonte
9
Desculpe, como você pode converter "melhor" em uma variável no seu primeiro exemplo? string.match(/best/i);
Doug Molineux
5
Por que você usaria .matchpara comparação booleana? Ele procura além do primeiro resultado. Você precisa parar após a primeira partida que .testou .searchfazer. Verifique o desempenho aqui .
Rami
toLowerCaseprovavelmente falhará no Teste da Turquia ( moserware.com/2008/02/does-your-code-pass-turkey-test.html ) e em problemas de conversão de casos semelhantes. Não sei como ReGexlidar com isso, mas se eu tivesse que adivinhar, diria melhor.
Ohad Schneider
3
@DougMolineux, você pode usar o construtor de objeto RegExp. var text = "best"; var exp = new RegExp(test, "i");. É o mesmo que /best/i.
Medeni Baykal 14/01/19
174

Substituir

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

com

var result= string.search(new RegExp(searchstring, "i"));
Sergey Ilinsky
fonte
7
Essa é uma maneira bastante confusa de contornar isso, pois são necessárias medidas para se proteger contra metacaracteres inesperados de regexp.
Dan
35
Dan, duvido que minha resposta mereça 1 de você. Tentei ajudar o ChrisBo corrigindo seu uso inadequado do JavaScript, a saber: var result = string.search (/ searchstring / i); para uma adequada, onde a cadeia de pesquisa variável foi usada da maneira que ele pretendia.
Sergey Ilinsky 7/10/08
8
Direita de Dan (embora ele provavelmente quis dizer " medidas"): s = 'a[b'; r = new RegExp(s)resulta em um erro de sintaxe (classe de caracteres não terminada)
Glenn Jackman
39

Se você estiver apenas procurando por uma string em vez de uma expressão regular mais complicada, poderá usar indexOf()- mas lembre-se de minúsculas as duas strings primeiro porque indexOf()diferencia maiúsculas de minúsculas:

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

Ou em uma única linha:

var result = string.toLowerCase().indexOf(searchstring.toLowerCase())>=0;
Odilon Refazer
fonte
24

Suponha que desejamos encontrar a variável string needlena variável string haystack. Existem três dicas:

  1. Aplicativos internacionalizados devem evitar string.toUpperCasee string.toLowerCase. Use uma expressão regular que ignore maiúsculas e minúsculas. Por exemplo, var needleRegExp = new RegExp(needle, "i");seguido porneedleRegExp.test(haystack) .
  2. Em geral, você pode não saber o valor de needle. Cuidado para needlenão conter caracteres especiais de expressão regular . Fuja deles usandoneedle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); .
  3. Em outros casos, se você deseja corresponder com precisão needlee haystack, apenas ignorando o caso, adicione "^"-o no início e "$"no final do construtor de expressões regulares.

Levando em consideração os pontos (1) e (2), um exemplo seria:

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);
Chris Chute
fonte
4

ES6 +:

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


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

includes()retorna truese searchStringaparecer em uma ou mais posições ou falsenão.

Andrey
fonte
2

Se você estiver preocupado com o caso "classe de caracteres não terminados", remover todos os caracteres não alfanuméricos seria útil:

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

Gosto da resposta do @ CHR15TO, ao contrário de outras respostas que já vi em outras perguntas semelhantes, essa resposta realmente mostra como escapar adequadamente uma sequência de pesquisa fornecida pelo usuário (em vez de dizer que seria necessário sem mostrar como).

No entanto, ainda é bastante desajeitado e possivelmente relativamente mais lento. Então, por que não ter uma solução específica para o que é provavelmente um requisito comum para codificadores? (E por que não incluí-lo na ES6 API BTW?)

Minha resposta [ https://stackoverflow.com/a/38290557/887092] em uma pergunta semelhante permite o seguinte:

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

Existem duas maneiras de comparação sem distinção entre maiúsculas e minúsculas:

  1. Converta seqüências de caracteres em maiúsculas e compare-as usando o operador strict ( ===). Como o operador rigoroso trata os operandos lê o material em: http://www.thesstech.com/javascript/relational-logical-operators

  2. Correspondência de padrões usando métodos de string:

    Use o método de string "search" para pesquisa que não diferencia maiúsculas de minúsculas. Leia sobre a pesquisa e outros métodos de string em: 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>
Sohail Arif
fonte
1

Faço isso com frequência e uso um protótipo simples de 5 linhas que aceita varargs. É rápido e funciona em qualquer lugar .

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

Steven Spungin
fonte
0

Você pode fazer tudo em minúsculas:

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

Percebi que se o usuário digitar uma sequência de texto, mas deixar a entrada sem selecionar nenhuma das opções de preenchimento automático, nenhum valor será definido na entrada oculta, mesmo que a sequência coincida com a da matriz. Então, com a ajuda das outras respostas, eu fiz isso:

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

            }
        } 
Atrás
fonte