Como comparar seqüências de caracteres ignorando o caso

171

Eu quero applee Applecomparação para ser true. Atualmente

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

Respostas:

273

Você está procurando casecmp. Retorna 0se duas cadeias são iguais, sem distinção entre maiúsculas e minúsculas.

str1.casecmp(str2) == 0

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

Como alternativa, você pode converter as duas seqüências para minúsculas ( str.downcase) e comparar para igualdade.

molf
fonte
19
De meus benchmarks casecmp é pelo menos duas vezes mais rápido que o método downcase
Jacob
77
casecmp: Um nome tolo para um caso- no método de comparar sensíveis ao ?!
Zabba
4
@Zabba: culpar o povo libc: pubs.opengroup.org/onlinepubs/9699919799/functions/...
mu é muito curta
17
Se você gosta de usar palavras, pode substituir == 0por #zero?
Andrew Grimm
3
Se você usar Rubocop a maneira correta para que não se queixam é "Apple".casecmp("APPLE").zero?Mas eu, pessoalmente, como Andres resposta abaixo, que usa.casecmp?
8bithero
45

No Ruby 2.4.0, você tem:casecmp?(other_str) → true, false, or nil

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

Aqui você tem mais informações

Andres
fonte
3
Uma boa melhoria no método, mas este é um dos métodos menos "sonoros de Ruby" que eu já vi. Parece que estou usando Java com esse casecmplixo.
Joshua Pinter
Honestamente, sugiro que você use "aBcDeF".downcase == "abcdef". Muito mais legível e os ganhos de desempenho do uso casecmpsão eliminados no Ruby 2.4+.
Joshua Pinter
Espere, qual seria a diferença entre ser falsee nilpara uma API assim ...
Trejkaz
De acordo com os documentos nil é retornado quando other_str não é uma string
ramblex
8

Caso você precise comparar as seqüências de caracteres UTF-8 que ignoram:

>> 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 assim no Ruby 2.3.1 e versões anteriores.

Para uma menor pegada de memória, você pode escolher string/multibyte:

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

Edite , Ruby 2.4.0:

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

Portanto casecmp, não funciona na 2.4.0; No entanto, na 2.4.0, pode-se comparar manualmente as strings UTF-8 sem active_supportgem:

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

casecmp e zero? são métodos embutidos em rubi. casecmp retorna 0 se duas cadeias são iguais, sem distinção entre maiúsculas e minúsculas e zero? verifica o valor zero (== 0)

str1.casecmp(str2).zero?
Sivalingam
fonte
Isso foi o que meu verificador de estilo me disse e eu gosto disso porque é mais claro do que comparar com literal 0, especialmente quando aninhado com uma condição mais envolvida.
Amos Shapira
5

Para ruby ​​2.4 funcionando bem casecmp? para strings utf-8 (mb_chars não é necessário):

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

mas o casecmp não está funcionando para o utf-8:

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