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

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.


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


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


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

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?

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.