Recherche insensible à la casse

272

J'essaie d'obtenir une recherche insensible à la casse avec deux chaînes en fonctionnement JavaScript.

Normalement, ce serait comme ceci:

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

Le /idrapeau serait insensible à la casse.

Mais je dois rechercher une deuxième chaîne; sans le drapeau, cela fonctionne parfaitement:

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

Si j'ajoute le /idrapeau à l'exemple ci-dessus, il rechercherait chaîne de recherche et non ce qui se trouve dans la variable "chaîne de recherche" (l'exemple suivant ne fonctionne pas):

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

Comment puis-je atteindre cet objectif?

Chris Boesing
la source

Réponses:

373

Ouais, utilisez .matchplutôt .search. Le résultat de l' .matchappel renverra la chaîne réelle qui a été mise en correspondance, mais elle peut toujours être utilisée comme valeur booléenne.

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

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

L'utilisation d'une expression régulière comme celle-ci est probablement la façon la plus simple et la plus évidente de le faire en JavaScript, mais gardez à l'esprit qu'il s'agit d' une expression régulière, et peut donc contenir des métacaractères d'expression régulière. Si vous voulez prendre la chaîne ailleurs (par exemple, entrée utilisateur), ou si vous voulez éviter d'avoir à échapper à beaucoup de métacaractères, alors vous êtes probablement mieux en utilisant indexOfcomme ceci:

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
la source
9
Désolé, comment pouvez-vous convertir "le meilleur" en variable dans votre premier exemple? string.match(/best/i);
Doug Molineux
5
Pourquoi utiliseriez-vous .matchpour la comparaison booléenne. Il recherche au-delà du premier résultat. Vous devez arrêter après le premier match qui .testou .searchfaire. Vérifiez les performances ici .
Rami
toLowerCaseéchouera très probablement le test de la Turquie ( moserware.com/2008/02/does-your-code-pass-turkey-test.html ) et des problèmes de conversion de cas similaires. Je ne sais pas comment ReGexça se passe, mais si je devais deviner, je dirais mieux.
Ohad Schneider
3
@DougMolineux vous pouvez utiliser le constructeur d'objet RegExp. var text = "best"; var exp = new RegExp(test, "i");. C'est la même chose que /best/i.
Medeni Baykal
174

Remplacer

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

avec

var result= string.search(new RegExp(searchstring, "i"));
Sergey Ilinsky
la source
7
C'est un moyen plutôt compliqué, car il prend des mesures pour se prémunir contre les métacaractères d'expression rationnelle inattendus.
Dan
35
Dan, je doute que ma réponse mérite -1 de votre part. J'ai essayé d'aider ChrisBo en corrigeant son utilisation incorrecte de JavaScript, à savoir: var result = string.search (/ searchstring / i); à un bon, où la chaîne de recherche variable a été utilisée comme il le souhaitait.
Sergey Ilinsky
8
Le droit de Dan (bien qu'il ait probablement voulu dire " aucune mesure"): s = 'a[b'; r = new RegExp(s)entraîne une erreur de syntaxe (classe de caractère
non terminée
39

Si vous recherchez simplement une chaîne plutôt qu'une expression régulière plus compliquée, vous pouvez utiliser indexOf()- mais n'oubliez pas de mettre les deux chaînes en minuscules en premier car elles indexOf()sont sensibles à la casse:

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 en une seule ligne:

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

Supposons que nous voulons trouver la variable chaîne needledans la variable chaîne haystack. Il y a trois pièges:

  1. Les applications internationalisées devraient éviter string.toUpperCaseet string.toLowerCase. Utilisez une expression régulière qui ignore la casse à la place. Par exemple, var needleRegExp = new RegExp(needle, "i");suivi de needleRegExp.test(haystack).
  2. En général, vous ne connaissez peut-être pas la valeur de needle. Attention, needleil ne contient aucun caractère spécial d' expression régulière . Échappez-les en utilisant needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");.
  3. Dans d'autres cas, si vous souhaitez faire correspondre précisément needleet haystack, en ignorant simplement la casse, assurez-vous d'ajouter "^"au début et "$"à la fin de votre constructeur d'expressions régulières.

Compte tenu des points (1) et (2), un exemple serait:

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
la source
4

ES6 +:

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


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

includes()renvoie truesi searchStringapparaît à une ou plusieurs positions ou falseautrement.

Andrey
la source
2

Si vous êtes préoccupé par le cas de la "classe de caractères non terminée", il serait utile de supprimer tous les caractères non alphanumériques:

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

J'aime la réponse de @ CHR15TO, contrairement à d'autres réponses que j'ai vues sur d'autres questions similaires, cette réponse montre comment échapper correctement une chaîne de recherche fournie par l'utilisateur (plutôt que de dire que cela serait nécessaire sans montrer comment).

Cependant, c'est encore assez maladroit, et peut-être relativement plus lent. Alors pourquoi ne pas avoir une solution spécifique à ce qui est probablement une exigence commune pour les codeurs? (Et pourquoi ne pas l'inclure dans l'ES6 API BTW?)

Ma réponse [ https://stackoverflow.com/a/38290557/887092] sur une question similaire permet ce qui suit:

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

Il existe deux façons de comparer la distinction insensible à la casse:

  1. Convertissez les chaînes en majuscules, puis comparez-les à l'aide de l'opérateur strict ( ===). Comment un opérateur strict traite les opérandes lire des trucs à: http://www.thesstech.com/javascript/relational-logical-operators

  2. Correspondance de modèle à l'aide de méthodes de chaîne:

    Utilisez la méthode de chaîne «recherche» pour une recherche insensible à la casse. Lisez à propos de la recherche et des autres méthodes de chaîne à: 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
la source
1

Je le fais souvent et j'utilise un simple prototype de 5 lignes qui accepte les varargs. Il est rapide et fonctionne partout .

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
la source
0

Vous pouvez tout mettre en minuscules:

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

J'ai remarqué que si l'utilisateur entre une chaîne de texte mais quitte l'entrée sans sélectionner aucune des options de saisie semi-automatique, aucune valeur n'est définie dans l'entrée masquée, même si la chaîne coïncide avec celle du tableau. Donc, avec l'aide des autres réponses, j'ai fait ceci:

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

            }
        } 
Depuis
la source