Как сравнить строки без учета регистра

171

Я хочу appleи Appleсравнение будет true. В настоящее время

"Apple" == "Apple"  # returns TRUE
"Apple" == "APPLE"  # returns FALSE
Стивен
источник

Ответы:

273

Ты ищешь casecmp. Возвращает, 0если две строки равны, без учета регистра.

str1.casecmp(str2) == 0

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

Кроме того, вы можете преобразовать обе строки в нижний регистр ( str.downcase) и сравнить на равенство.

Molf
источник
19
Из моих тестов casecmp как минимум в два раза быстрее метода downcase
Джейкоб
77
casecmp: Глупое название для прецедентного в , чувствительного сравнить метод ?!
Забба
4
@Zabba: Виноваты люди из libc: pubs.opengroup.org/onlinepubs/9699919799/functions/…
мю слишком мало
17
Если вам нравится с помощью слов, вы можете заменить == 0сzero?
Andrew Grimm
3
Если вы используете Rubocop, правильный способ не жаловаться, "Apple".casecmp("APPLE").zero?но лично мне нравится ответ Андреса ниже, который использует.casecmp?
8bithero
45

В Ruby 2.4.0 у вас есть:casecmp?(other_str) → true, false, or nil

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

Здесь у вас есть больше информации

Andres
источник
3
Хорошее улучшение метода, но это один из наименее "звучащих на Ruby" методов, которые я когда-либо видел. Такое ощущение, что я использую Java с этим casecmpмусором.
Джошуа Пинтер
Я бы честно предложил использовать "aBcDeF".downcase == "abcdef"вместо этого. Гораздо более удобочитаемы, а прирост casecmpпроизводительности устранен в Ruby 2.4+.
Джошуа Пинтер
Подождите, какая будет разница между falseи nilдля API, подобного этому ...
Trejkaz
Согласно документам ноль возвращается, когда other_str не является строкой
ramblex
8

Если вам нужно сравнить строки UTF-8 без учета регистра:

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

Это работает в Ruby 2.3.1 и более ранних версиях.

Для меньшего объема памяти вы можете выбрать вишню string/multibyte:

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

Редактировать , Ruby 2.4.0:

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

Так casecmpчто не работает в 2.4.0; Однако в 2.4.0 можно сравнивать строки UTF-8 вручную без active_supportгема:

>> str1.downcase == str2.downcase
=> true
саман
источник
5

casecmp и ноль? Рубиновые встроенные методы. casecmp возвращает 0, если две строки равны, без учета регистра и ноль? проверяет нулевое значение (== 0)

str1.casecmp(str2).zero?
Sivalingam
источник
Это то, что сказал мне мой контролер стиля, и мне это нравится, потому что это понятнее, чем сравнение с литералом 0, особенно когда он вложен в более сложное условие.
Амос Шапира
5

Для ruby ​​2.4 работает нормально casecmp? для строк utf-8 (mb_chars не требуется):

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

но casecmp не работает для utf-8:

2.4.1 :062 > 'строка1'.casecmp('СтроКА1')
 => 1
2.4.1 :063 > 'string1'.casecmp('StrInG1')
 => 0
Серхио Белевский
источник