Comment puis-je effectuer une comparaison de chaînes sans distinction de casse en JavaScript?
Le moyen le plus simple de le faire (si vous n'êtes pas inquiet à propos des caractères Unicode spéciaux) est d'appeler toUpperCase
:
var areEqual = string1.toUpperCase() === string2.toUpperCase();
EDIT: Cette réponse a été ajoutée il y a 9 ans. Aujourd'hui, vous devriez utiliser localeCompare
avec l'option sensitivity: 'accent'
:
function ciEquals(a, b) {
return typeof a === 'string' && typeof b === 'string'
? a.localeCompare(b, undefined, { sensitivity: 'accent' }) === 0
: a === b;
}
console.log("'a' = 'a'?", ciEquals('a', 'a'));
console.log("'AaA' = 'aAa'?", ciEquals('AaA', 'aAa'));
console.log("'a' = 'á'?", ciEquals('a', 'á'));
console.log("'a' = 'b'?", ciEquals('a', 'b'));
Le { sensitivity: 'accent' }
indique à localeCompare()
de traiter deux variantes de la même lettre de base comme la même sauf leurs accents sont différents (comme dans le troisième exemple) ci-dessus.
Vous pouvez également utiliser { sensitivity: 'base' }
, qui traite deux caractères comme équivalents tant que leur caractère de base est identique (donc A
sera traité comme équivalent à á
).
Notez que le troisième paramètre de localeCompare
n'est pas pris en charge dans IE10 ou version antérieure, ni dans certains navigateurs mobiles (voir le tableau de compatibilité de la page liée ci-dessus). Par conséquent, si vous avez besoin de prendre en charge ces navigateurs, vous devrez se retirer:
function ciEqualsInner(a, b) {
return a.localeCompare(b, undefined, { sensitivity: 'accent' }) === 0;
}
function ciEquals(a, b) {
if (typeof a !== 'string' || typeof b !== 'string') {
return a === b;
}
// v--- feature detection
return ciEqualsInner('A', 'a')
? ciEqualsInner(a, b)
: /* fallback approach here */;
}
_ {Réponse originale
La meilleure façon de faire une comparaison en JavaScript sans tenir compte de la casse est d'utiliser la méthode RegExp match()
avec l'indicateur i
.
Recherche insensible à la casse
Lorsque les deux chaînes comparées sont des variables (et non des constantes), c'est un peu plus compliqué, car vous devez générer un RegExp à partir de la chaîne, mais le passage de cette chaîne au constructeur RegExp peut entraîner des correspondances incorrectes ou des correspondances manquantes si la chaîne a une expression régulière spéciale. personnages dedans.
Si l'internationalisation vous tient à cœur, n'utilisez pas toLowerCase()
ou toUpperCase()
, car cela ne permet pas des comparaisons précises sans distinction de casse dans toutes les langues.
Avec l'aide de l'expression régulière, nous pouvons également réaliser.
(/keyword/i).test(source)
/i
est pour ignorer la casse. Si ce n’est pas nécessaire, nous pouvons ignorer et tester la correspondance sensible à la casse comme
(/keyword/).test(source)
N'oubliez pas que le boîtier est une opération spécifique aux paramètres régionaux. Selon le scénario, vous voudrez peut-être en tenir compte. Par exemple, si vous comparez les noms de deux personnes, vous voudrez peut-être prendre en compte les paramètres régionaux mais si vous comparez des valeurs générées par la machine telles que UUID, vous ne le ferez peut-être pas. C'est pourquoi j'utilise la fonction suivante dans ma bibliothèque utils (notez que la vérification de type n'est pas incluse pour des raisons de performances).
function compareStrings (string1, string2, ignoreCase, useLocale) {
if (ignoreCase) {
if (useLocale) {
string1 = string1.toLocaleLowerCase();
string2 = string2.toLocaleLowerCase();
}
else {
string1 = string1.toLowerCase();
string2 = string2.toLowerCase();
}
}
return string1 === string2;
}
Comme indiqué dans de récents commentaires, string::localCompare
prend en charge les comparaisons insensibles à la casse (entre autres éléments puissants).
Voici un exemple simple
'xyz'.localeCompare('XyZ', undefined, { sensitivity: 'base' }); // returns 0
Et une fonction générique que vous pourriez utiliser
function equalsIgnoringCase(text, other) {
text.localeCompare(other, undefined, { sensitivity: 'base' }) === 0;
}
Notez qu'au lieu de undefined
, vous devriez probablement entrer les paramètres régionaux avec lesquels vous travaillez. Ceci est important comme indiqué dans les documents MDN
en suédois, ä et a sont des lettres de base séparées
À la date de publication, UC Browser pour Android et Opera Mini ne pas prend en charge locale et options paramètres. Veuillez vérifier https://caniuse.com/#search=localeCompare pour obtenir des informations à jour.
J'ai récemment créé une micro-bibliothèque fournissant des aides pour les chaînes qui ne respectent pas la casse: https://github.com/nickuraltsev/ignore-case . (Il utilise toUpperCase
en interne.)
var ignoreCase = require('ignore-case');
ignoreCase.equals('FOO', 'Foo'); // => true
ignoreCase.startsWith('foobar', 'FOO'); // => true
ignoreCase.endsWith('foobar', 'BaR'); // => true
ignoreCase.includes('AbCd', 'c'); // => true
ignoreCase.indexOf('AbCd', 'c'); // => 2
si vous êtes préoccupé par le sens de l'inégalité (peut-être souhaitez-vous trier une liste) vous devez effectuer la conversion de casse en assez grande quantité, et comme il existe plus de caractères minuscules dans unicode que de majuscules, la meilleure conversion est probablement la meilleure utiliser.
function my_strcasecmp( a, b )
{
if((a+'').toLowerCase() > (b+'').toLowerCase()) return 1
if((a+'').toLowerCase() < (b+'').toLowerCase()) return -1
return 0
}
Javascript semble utiliser les paramètres régionaux "C" pour les comparaisons de chaînes afin que l'ordre résultant soitbe moche si les chaînes contiennent des lettres autres que ASCII. on ne peut pas faire grand chose à ce sujet sans faire une inspection beaucoup plus détaillée des cordes.
Supposons que nous voulions trouver la variable chaîne needle
dans la variable chaîne haystack
. Il y a trois pièges:
string.toUpperCase
et string.toLowerCase
. Utilisez une expression régulière qui ignore la casse. Par exemple, var needleRegExp = new RegExp(needle, "i");
suivi de needleRegExp.test(haystack)
.needle
. Veillez à ce que needle
ne contienne aucune expression régulière caractères spéciaux . Échappez-vous avec needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
.needle
et haystack
, en ignorant simplement la casse, veillez à ajouter "^"
au début et "$"
à la fin de votre constructeur d'expression régulière.En prenant en considération les 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);
if (result) {
// Your code here
}
Beaucoup de réponses ici, mais j'aime bien ajouter une solution basée sur l'extension de la librairie String:
String.prototype.equalIgnoreCase = function(str)
{
return (str != null
&& typeof str === 'string'
&& this.toUpperCase() === str.toUpperCase());
}
De cette façon, vous pouvez simplement l'utiliser comme vous le faites en Java!
Exemple:
var a = "hello";
var b = "HeLLo";
var c = "world";
if (a.equalIgnoreCase(b)) {
document.write("a == b");
}
if (a.equalIgnoreCase(c)) {
document.write("a == c");
}
if (!b.equalIgnoreCase(c)) {
document.write("b != c");
}
La sortie sera:
"a == b"
"b != c"
String.prototype.equalIgnoreCase = function(str) {
return (str != null &&
typeof str === 'string' &&
this.toUpperCase() === str.toUpperCase());
}
var a = "hello";
var b = "HeLLo";
var c = "world";
if (a.equalIgnoreCase(b)) {
document.write("a == b");
document.write("<br>");
}
if (a.equalIgnoreCase(c)) {
document.write("a == c");
}
if (!b.equalIgnoreCase(c)) {
document.write("b != c");
}
Il y a deux manières de faire une comparaison insensible à la casse:
===
). Comment un opérateur strict traite les opérandes en lisant les choses à: http://www.thesstech.com/javascript/relational-logical-operatorsUtilisez la méthode de chaîne "search" pour la recherche ne respectant pas la casse . Pour en savoir plus sur la recherche et les autres méthodes de chaîne, rendez-vous à l'adresse suivante: 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>
str = 'Lol', str2 = 'lOl', regex = new RegExp('^' + str + '$', 'i');
if (regex.test(str)) {
console.log("true");
}
utilisez regex pour la correspondance ou la comparaison de chaînes,
en javaScript, vous pouvez utiliser match () pour comparer les chaînes, n'oubliez pas de mettre i dans regex
exemple :
var matchString = "Test" ;
if(matchString.match(/test/i) ){
alert('String matched) ;
}else{
alert('String not matched') ;
}
Pourquoi ne pas lancer d'exceptions et NE PAS utiliser une expression régulière lente?
return str1 != null && str2 != null
&& typeof str1 === 'string' && typeof str2 === 'string'
&& str1.toUpperCase() === str2.toUpperCase();
L'extrait ci-dessus suppose que vous ne voulez pas faire correspondre si l'une des chaînes est nulle ou indéfinie.
Si vous voulez faire correspondre null/undefined, alors:
return (str1 == null && str2 == null)
|| (str1 != null && str2 != null
&& typeof str1 === 'string' && typeof str2 === 'string'
&& str1.toUpperCase() === str2.toUpperCase());
Si pour une raison quelconque vous vous souciez de undefined vs null:
return (str1 === undefined && str2 === undefined)
|| (str1 === null && str2 === null)
|| (str1 != null && str2 != null
&& typeof str1 === 'string' && typeof str2 === 'string'
&& str1.toUpperCase() === str2.toUpperCase());
Même cette question a déjà répondu. J'ai une approche différente pour utiliser RegExp et correspondre pour ignorer la casse. S'il vous plaît voir mon lien https://jsfiddle.net/marchdave/7v8bd7dq/27/
$("#btnGuess").click(guessWord);
function guessWord() {
var letter = $("#guessLetter").val();
var Word = 'ABC';
var pattern = RegExp(letter, 'gi'); // pattern: /a/gi
var result = Word.match(pattern);
alert('Ignore case sensitive:' + result);
}
J'ai écrit une extension. très trivial
if (typeof String.prototype.isEqual!= 'function') {
String.prototype.isEqual = function (str){
return this.toUpperCase()==str.toUpperCase();
};
}
Si les deux chaînes ont les mêmes paramètres régionaux connus, vous pouvez utiliser un objet Intl.Collator
comme ceci:
function equalIgnoreCase(s1: string, s2: string) {
return new Intl.Collator("en-US", { sensitivity: "base" }).compare(s1, s2) === 0;
}
Évidemment, vous voudrez peut-être mettre en cache la Collator
pour une meilleure efficacité.
L'avantage de cette approche est qu'elle devrait être beaucoup plus rapide que RegExps et repose sur un ensemble extrêmement personnalisable (voir la description des paramètres du constructeur locales
et options
dans l'article ci-dessus) de collateurs prêts à l'emploi.
Puisqu'aucune réponse ne fournissait clairement un extrait de code simple d'utilisation de RegExp
, voici ma tentative:
function compareInsensitive(str1, str2){
return typeof str1 === 'string' &&
typeof str2 === 'string' &&
new RegExp("^" + str1.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + "$", "i").test(str2);
}
Il présente plusieurs avantages:
undefined
par exemple, planterait une expression comme str1.toUpperCase()
).RegExp
.Ceci est une version améliorée de cette réponse .
String.equal = function (s1, s2, ignoreCase, useLocale) {
if (s1 == null || s2 == null)
return false;
if (!ignoreCase) {
if (s1.length !== s2.length)
return false;
return s1 === s2;
}
if (useLocale) {
if (useLocale.length)
return s1.toLocaleLowerCase(useLocale) === s2.toLocaleLowerCase(useLocale)
else
return s1.toLocaleLowerCase() === s2.toLocaleLowerCase()
}
else {
if (s1.length !== s2.length)
return false;
return s1.toLowerCase() === s2.toLowerCase();
}
}
String.equal = function (s1, s2, ignoreCase, useLocale) {
if (s1 == null || s2 == null)
return false;
if (!ignoreCase) {
if (s1.length !== s2.length)
return false;
return s1 === s2;
}
if (useLocale) {
if (useLocale.length)
return s1.toLocaleLowerCase(useLocale) === s2.toLocaleLowerCase(useLocale)
else
return s1.toLocaleLowerCase() === s2.toLocaleLowerCase()
}
else {
if (s1.length !== s2.length)
return false;
return s1.toLowerCase() === s2.toLowerCase();
}
}
// If you don't mind extending the prototype.
String.prototype.equal = function(string2, ignoreCase, useLocale) {
return String.equal(this.valueOf(), string2, ignoreCase, useLocale);
}
// ------------------ TESTS ----------------------
console.log("Tests...");
console.log('Case sensitive 1');
var result = "Abc123".equal("Abc123");
console.assert(result === true);
console.log('Case sensitive 2');
result = "aBC123".equal("Abc123");
console.assert(result === false);
console.log('Ignore case');
result = "AbC123".equal("aBc123", true);
console.assert(result === true);
console.log('Ignore case + Current locale');
result = "AbC123".equal("aBc123", true);
console.assert(result === true);
console.log('Turkish test 1 (ignore case, en-US)');
result = "IiiI".equal("ıiİI", true, "en-US");
console.assert(result === false);
console.log('Turkish test 2 (ignore case, tr-TR)');
result = "IiiI".equal("ıiİI", true, "tr-TR");
console.assert(result === true);
console.log('Turkish test 3 (case sensitive, tr-TR)');
result = "IiiI".equal("ıiİI", false, "tr-TR");
console.assert(result === false);
console.log('null-test-1');
result = "AAA".equal(null);
console.assert(result === false);
console.log('null-test-2');
result = String.equal(null, "BBB");
console.assert(result === false);
console.log('null-test-3');
result = String.equal(null, null);
console.assert(result === false);
Convertissez les deux en abaissement (une seule fois pour des raisons de performances) et comparez-les avec l'opérateur ternaire sur une seule ligne:
function strcasecmp(s1,s2){
s1=(s1+'').toLowerCase();
s2=(s2+'').toLowerCase();
return s1>s2?1:(s1<s2?-1:0);
}