Comment comparer des chaînes en ignorant la casse

171

Je veux appleet Applecomparaison d'être true. Actuellement

"Apple" == "Apple"  # returns TRUE
"Apple" == "APPLE"  # returns FALSE
Steven
la source

Réponses:

273

Vous cherchez casecmp. Il renvoie 0si deux chaînes sont égales, sans tenir compte de la casse.

str1.casecmp(str2) == 0

"Apple".casecmp("APPLE") == 0
#=> true

Vous pouvez également convertir les deux chaînes en minuscules ( str.downcase) et comparer pour l'égalité.

molf
la source
19
D'après mes repères, casecmp est au moins deux fois plus rapide que la méthode downcase
Jacob
77
casecmp: un nom idiot pour une méthode de comparaison sensible à la casse?!
Zabba
4
@Zabba: Blâmez les gens de la libc: pubs.opengroup.org/onlinepubs/9699919799/functions/…
mu est trop court
17
Si vous aimez utiliser des mots, vous pouvez remplacer le == 0parzero?
Andrew Grimm
3
Si vous utilisez Rubocop, la bonne façon de ne pas se plaindre est "Apple".casecmp("APPLE").zero?Mais personnellement, j'aime la réponse d'Andres ci-dessous, qui utilise.casecmp?
8bithero
45

Dans Ruby 2.4.0, vous avez:casecmp?(other_str) → true, false, or nil

"abcdef".casecmp?("abcde")     #=> false
"aBcDeF".casecmp?("abcdef")    #=> true
"abcdef".casecmp?("abcdefg")   #=> false
"abcdef".casecmp?("ABCDEF")    #=> true

Ici vous avez plus d'informations

Andrés
la source
3
Une bonne amélioration de la méthode mais c'est l'une des méthodes les moins «rubis» que j'ai jamais vues. J'ai l'impression d'utiliser Java avec ces casecmpfichiers indésirables.
Joshua Pinter
Je vous suggère honnêtement d'utiliser à la "aBcDeF".downcase == "abcdef"place. Beaucoup plus lisible et les gains de performances de l'utilisation casecmpsont éliminés dans Ruby 2.4+.
Joshua Pinter
Attendez, quelle serait la différence entre falseet nilpour une API comme celle-ci ...
Trejkaz
Selon la documentation, nil est renvoyé lorsque other_str n'est pas une chaîne
ramblex
8

Si vous devez comparer les chaînes UTF-8 en ignorant la casse:

>> str1 = "Мария"
=> "Мария"
>> str2 = "мария"
=> "мария"
>> str1.casecmp(str2) == 0
=> false
>> require 'active_support/all'
=> true
>> str1.mb_chars.downcase.to_s.casecmp(str2.mb_chars.downcase.to_s) == 0
=> true

Cela fonctionne de cette façon dans Ruby 2.3.1 et les versions antérieures.

Pour une plus petite empreinte mémoire, vous pouvez choisir string/multibyte:

require 'active_support'
require 'active_support/core_ext/string/multibyte'

Modifier , Ruby 2.4.0:

>> str1.casecmp(str2) == 0
=> false

Cela casecmpne fonctionne donc pas dans 2.4.0; Cependant, dans la version 2.4.0, on peut comparer manuellement les chaînes UTF-8 sans active_supportgem:

>> str1.downcase == str2.downcase
=> true
Adobe
la source
5

casecmp et zéro? sont des méthodes intégrées de rubis. casecmp renvoie 0 si deux chaînes sont égales, insensible à la casse et zéro? vérifie la valeur zéro (== 0)

str1.casecmp(str2).zero?
Sivalingam
la source
C'est ce que m'a dit mon vérificateur de style, et je l'aime parce que c'est plus clair que de comparer avec le littéral 0, surtout lorsqu'il est imbriqué avec une condition plus impliquée.
Amos Shapira
5

Pour ruby ​​2.4 fonctionne bien casecmp? pour les chaînes utf-8 (mb_chars non nécessaires):

2.4.1 :062 > 'строка1'.casecmp?('СтроКа1')
 => true

mais casecmp ne fonctionne pas pour utf-8:

2.4.1 :062 > 'строка1'.casecmp('СтроКА1')
 => 1
2.4.1 :063 > 'string1'.casecmp('StrInG1')
 => 0
Sergio Belevskij
la source