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

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é.


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


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


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

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?

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.