Cómo comparar cadenas ignorando el caso

171

Quiero appley Applecomparación para ser true. Actualmente

"Apple" == "Apple"  # returns TRUE
"Apple" == "APPLE"  # returns FALSE
Steven
fuente

Respuestas:

273

Usted está buscando casecmp. Regresa 0si dos cadenas son iguales, sin distinción entre mayúsculas y minúsculas.

str1.casecmp(str2) == 0

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

Alternativamente, puede convertir ambas cadenas a minúsculas ( str.downcase) y comparar para igualdad.

molf
fuente
19
Desde mis puntos de referencia, casecmp es al menos dos veces más rápido que el método de mayúsculas y minúsculas
Jacob,
77
casecmp: ¿un nombre tonto para un método de comparación caso- en- sensible?
Zabba
44
@Zabba: Culpe a la gente de la biblioteca
mu es demasiado corto
17
Si te gusta usar palabras, puedes reemplazarlas == 0conzero?
Andrew Grimm
3
Si usa Rubocop, la forma correcta para que no se queje es "Apple".casecmp("APPLE").zero?Pero personalmente me gusta que Andrés responda a continuación, que usa.casecmp?
8bithero
45

En Ruby 2.4.0 tienes:casecmp?(other_str) → true, false, or nil

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

Aquí tienes más información

Andres
fuente
3
Una buena mejora para el método, pero este es uno de los menos métodos de "sonar rubí" que he visto. Parece que estoy usando Java con esta casecmpbasura.
Joshua Pinter el
Sinceramente, te sugiero que uses "aBcDeF".downcase == "abcdef"en su lugar. Mucho más legible y las ganancias de rendimiento del uso casecmpse eliminan en Ruby 2.4+.
Joshua Pinter
Espera, ¿cuál sería la diferencia entre falsey nilpara una API como esta ...
Trejkaz
Según los documentos, se devuelve nil cuando other_str no es una cadena
ramblex
8

En caso de que tenga que comparar cadenas UTF-8 ignorando mayúsculas y minúsculas:

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

Funciona de esta manera en Ruby 2.3.1 y versiones anteriores.

Para una huella de memoria más pequeña, puede elegir string/multibyte:

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

Editar , Ruby 2.4.0:

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

Entonces casecmpno funciona en 2.4.0; Sin embargo, en 2.4.0 se pueden comparar cadenas UTF-8 manualmente sin active_supportgemas:

>> str1.downcase == str2.downcase
=> true
Adobe
fuente
5

casecmp y cero? son métodos incorporados de rubí. casecmp devuelve 0 si dos cadenas son iguales, sin distinción entre mayúsculas y minúsculas? comprueba el valor cero (== 0)

str1.casecmp(str2).zero?
Sivalingam
fuente
Eso es lo que me dijo mi comprobador de estilo, y me gusta porque es más claro que compararlo con el literal 0, especialmente cuando está anidado con una condición más complicada.
Amos Shapira
5

¿Para ruby ​​2.4 funciona bien casecmp? para cadenas utf-8 (no se necesitan mb_chars):

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

pero casecmp no funciona para utf-8:

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