Búsqueda sin distinción entre mayúsculas y minúsculas

272

Estoy tratando de obtener una búsqueda que no distinga entre mayúsculas y minúsculas con dos cadenas en JavaScript funcionando.

Normalmente sería así:

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

La /ibandera sería para mayúsculas y minúsculas.

Pero necesito buscar una segunda cadena; sin la bandera funciona perfecto:

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

Si agrego el /iindicador al ejemplo anterior, buscaría la cadena de búsqueda y no lo que está en la variable "cadena de búsqueda" (el siguiente ejemplo no funciona):

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

¿Cómo puedo conseguir esto?

Chris Boesing
fuente

Respuestas:

373

Sí, uso .match, en lugar de .search. El resultado de la .matchllamada devolverá la cadena real que coincidió, pero aún puede usarse como un valor booleano.

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

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

Usar una expresión regular como esa es probablemente la forma más ordenada y obvia de hacerlo en JavaScript, pero tenga en cuenta que es una expresión regular y, por lo tanto, puede contener metacaracteres regex. Si desea tomar la cadena de otra parte (por ejemplo, entrada del usuario), o si desea evitar tener que escapar de muchos metacaracteres, entonces probablemente sea mejor usarlo indexOfasí:

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
fuente
9
Lo sentimos, ¿cómo puedes convertir "mejor" en una variable en tu primer ejemplo? string.match(/best/i);
Doug Molineux el
55
¿Por qué .matchusarías para la comparación booleana? Busca más allá del primer resultado. Debe detenerse después del primer partido que .testo .searchhacer. Comprueba el rendimiento aquí .
Rami
toLowerCaseLo más probable es que falle la Prueba de Turquía ( moserware.com/2008/02/does-your-code-pass-turkey-test.html ) y problemas de conversión de casos similares. No estoy seguro de cómo lo ReGexmaneja, pero si tuviera que adivinar diría mejor.
Ohad Schneider
3
@DougMolineux puedes usar el constructor de objetos RegExp. var text = "best"; var exp = new RegExp(test, "i");. Esto es lo mismo que /best/i.
Medeni Baykal
174

Reemplazar

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

con

var result= string.search(new RegExp(searchstring, "i"));
Sergey Ilinsky
fuente
77
Esa es una forma bastante desordenada de evitarlo, ya que toma medidas para protegerse contra metacaracteres de expresiones regulares inesperadas.
Dan
35
Dan, dudo que mi respuesta merezca -1 de tu parte. Intenté ayudar a ChrisBo corrigiendo su uso incorrecto de JavaScript, a saber: var result = string.search (/ searchstring / i); a una adecuada, donde la cadena de búsqueda variable se usó de la manera que pretendía.
Sergey Ilinsky
8
Dan tiene razón (aunque probablemente quiso decir " sin medidas"): s = 'a[b'; r = new RegExp(s)da como resultado un error de sintaxis (clase de caracteres sin terminar)
glenn jackman
39

Si solo está buscando una cadena en lugar de una expresión regular más complicada, puede usar indexOf(), pero recuerde poner en minúscula ambas cadenas primero porque indexOf()distingue entre mayúsculas y 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);

O en una sola línea:

var result = string.toLowerCase().indexOf(searchstring.toLowerCase())>=0;
Odilon Redo
fuente
24

Supongamos que queremos encontrar la variable de cadena needleen la variable de cadena haystack. Hay tres trampas:

  1. Las aplicaciones internacionalizadas deben evitarse string.toUpperCasey string.toLowerCase. Utilice una expresión regular que ignore mayúsculas y minúsculas. Por ejemplo, var needleRegExp = new RegExp(needle, "i");seguido de needleRegExp.test(haystack).
  2. En general, es posible que no conozca el valor de needle. Tenga cuidado de que needleno contenga ninguna expresión especial de caracteres especiales . Escapar de estos utilizando needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");.
  3. En otros casos, si desea hacer coincidir con precisión needley haystack, simplemente ignorando mayúsculas y minúsculas, asegúrese de agregar "^"al comienzo y "$"al final de su constructor de expresiones regulares.

Teniendo en cuenta los puntos (1) y (2), un ejemplo sería:

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
fuente
4

ES6 +:

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


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

includes()devuelve truesi searchStringaparece en una o más posiciones o de falseotra manera.

Andrey
fuente
2

Si le preocupa el caso de "clase de caracteres no terminados", sería útil eliminar todos los caracteres no alfanuméricos:

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

Me gusta la respuesta de @ CHR15TO, a diferencia de otras respuestas que he visto en otras preguntas similares, esa respuesta realmente muestra cómo escapar correctamente de una cadena de búsqueda proporcionada por el usuario (en lugar de decir que sería necesario sin mostrar cómo).

Sin embargo, todavía es bastante torpe, y posiblemente relativamente más lento. Entonces, ¿por qué no tener una solución específica para lo que probablemente sea un requisito común para los codificadores? (¿Y por qué no incluirlo en la ES6 API BTW?)

Mi respuesta [ https://stackoverflow.com/a/38290557/887092] en una pregunta similar permite lo siguiente:

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

Hay dos formas de comparación entre mayúsculas y minúsculas:

  1. Convierta cadenas en mayúsculas y luego compárelas usando el operador estricto ( ===). Cómo el operador estricto trata los operandos lee cosas en: http://www.thesstech.com/javascript/relational-logical-operators

  2. Coincidencia de patrones utilizando métodos de cadena:

    Utilice el método de cadena "buscar" para la búsqueda sin distinción entre mayúsculas y minúsculas. Lea sobre la búsqueda y otros métodos de cadena en: 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
fuente
1

Hago esto a menudo y uso un prototipo simple de 5 líneas que acepta varargs. Es rápido y funciona en todas partes .

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
fuente
0

Puedes poner todo en minúsculas:

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

Noté que si el usuario ingresa una cadena de texto pero deja la entrada sin seleccionar ninguna de las opciones de autocompletar, no se establece ningún valor en la entrada oculta, incluso si la cadena coincide con una en la matriz. Entonces, con la ayuda de las otras respuestas, hice esto:

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

            }
        } 
Hace
fuente