Метод upcase
использует всю строку в целом.
Мне нужно загладить только первую букву.
Кроме того, мне нужно поддерживать несколько популярных языков, таких как немецкий и русский.
Как мне это сделать?
Метод upcase
использует всю строку в целом.
Мне нужно загладить только первую букву.
Кроме того, мне нужно поддерживать несколько популярных языков, таких как немецкий и русский.
Как мне это сделать?
Это зависит от используемой вами версии Ruby.
Ruby 2.4 и выше
Это просто работает, так как с этой версии ruby поддерживает сопоставление регистров Unicode.
"мария".capitalize #=> Мария
Ruby 2.3 и ниже
"maria".capitalize #=> "Maria"
"мария".capitalize #=> мария
Проблема в том, что он просто не делает то, что вы хотите: он выводит мария
вместо Мария
.
Если вы используете Rails, есть простой обходной путь:
"мария".mb_chars.capitalize.to_s # requires ActiveSupport::Multibyte
делает работу
В противном случае вам нужно будет установить гем юникода и использовать его так:
require 'unicode'
Unicode::capitalize("мария") #=> Мария
Ruby 1.8
Прежде всего, обязательно используйте магический комментарий кодирования:
#!/usr/bin/env ruby
puts "мария".capitalize
дает invalid multibyte char (US-ASCII)
, в то время как:
#!/usr/bin/env ruby
#coding: utf-8
puts "мария".capitalize
работает без ошибок, но также см. Ruby 2.3 и нижний раздел для реальной заглавной буквы.
заглавная буква первой строки строки
"kirk douglas".capitalize
#=> "Kirk douglas"
загладить первую букву каждого слова
В рельсах:
"kirk douglas".titleize
=> "Kirk Douglas"
ИЛИ
"kirk_douglas".titleize
=> "Kirk Douglas"
В рубине:
"kirk douglas".split(/ |\_|\-/).map(&:capitalize).join(" ")
#=> "Kirk Douglas"
вне рельсов, но все еще хочет использовать метод titleize
require 'active_support/core_ext'
"kirk douglas".titleize #or capitalize
К сожалению, невозможно, чтобы машина правильно вставила/опущена/заглавная буква. Для понимания этого компьютера требуется слишком много контекстуальной информации.
Итак, почему класс Ruby String
поддерживает только капитализацию символов ASCII, потому что там он хотя бы несколько четко определен.
Что я подразумеваю под "контекстной информацией"?
Например, чтобы правильно использовать i
, вам нужно знать, на каком языке находится текст. Например, у английского языка есть только два i
s: capital i
без точки и маленького i
с точка. Но у турецкого есть четыре i
s: capital i
без точки, столица İ
с точкой, маленькая ı
без точки, маленькая i
с точкой. Итак, на английском языке 'i'.upcase # => 'I'
и на турецком языке 'i'.upcase # => 'İ'
. Другими словами: поскольку 'i'.upcase
может возвращать два разных результата, в зависимости от языка, очевидно, что невозможно правильно загладить слово, не зная его языка.
Но Ruby не знает языка, он знает только кодировку. Поэтому невозможно правильно использовать строку с встроенными функциями Ruby.
Ухудшается: даже зная язык, иногда невозможно сделать капитализацию должным образом. Например, на немецком языке 'Maße'.upcase # => 'MASSE'
(Maße - множественное число значений значения Maß). Однако 'Masse'.upcase # => 'MASSE'
(что означает масса). Итак, что такое 'MASSE'.capitalize
? Другими словами: правильная капитализация требует полномасштабного Искусственного интеллекта.
Таким образом, вместо того, чтобы иногда давать неправильный ответ, Ruby выбирает, чтобы иногда вообще не давать ответа, поэтому символы, отличные от ASCII, просто игнорируются в операциях downcase/upcase/capize. (Который, конечно, также читает неверные результаты, но, по крайней мере, легко проверить.)
Ну, просто, чтобы мы знали, как использовать только первую букву и оставить их в покое (потому что иногда это то, что нужно)...
['NASA', 'MHz', 'sputnik'].collect do |word|
letters = word.split('')
letters.first.upcase!
letters.join
end
=> ["NASA", "MHz", "Sputnik"]
Вызов #capitalize приведет к ["Nasa", "Mhz", "Sputnik"]
В Active Directory и Rails 5.0.0.beta4 вы можете использовать один из двух методов: String#upcase_first
или ActiveSupport::Inflector#upcase_first
. Подробнее см. сообщение в блоге.
Используйте capitalize
. Из docs:
Возвращает копию str с первым символом, преобразованным в верхний регистр, а остальное - в нижний регистр.
"hello".capitalize #=> "Hello"
"HELLO".capitalize #=> "Hello"
"123ABC".capitalize #=> "123abc"
Вы можете использовать mb_chars
. Это относится к умлаут:
class String
# Only capitalize first letter of a string
def capitalize_first
self[0] = self[0].mb_chars.upcase
self
end
end
Пример:
"ümlaute".capitalize_first
#=> "Ümlaute"
Ниже приведен еще один способ использовать каждое слово в строке. \w
не сопоставляет кириллицу или латинские буквы с диакритическими знаками, но [[:word:]]
. upcase
, downcase
, capitalize
и swapcase
не обращался к не-ASCII символы, пока Руби 2.4.0, который был выпущен в 2016 году.
"aAa-BBB ä мария _a a_a".gsub(/\w+/,&:capitalize)
=> "Aaa-Bbb ä мария _a A_a"
"aAa-BBB ä мария _a a_a".gsub(/[[:word:]]+/,&:capitalize)
=> "Aaa-Bbb Ä Мария _a A_a"
[[:word:]]
соответствует символам в следующих категориях:
Ll (Letter, Lowercase)
Lu (Letter, Uppercase)
Lt (Letter, Titlecase)
Lo (Letter, Other)
Lm (Letter, Modifier)
Nd (Number, Decimal Digit)
Pc (Punctuation, Connector)
[[:word:]]
соответствует всем 10 символам в категории "Знаки пунктуации" (Pc
):
005F _ LOW LINE
203F ‿ UNDERTIE
2040 ⁀ CHARACTER TIE
2054 ⁔ INVERTED UNDERTIE
FE33 ︳ PRESENTATION FORM FOR VERTICAL LOW LINE
FE34 ︴ PRESENTATION FORM FOR VERTICAL WAVY LOW LINE
FE4D ﹍ DASHED LOW LINE
FE4E ﹎ CENTRELINE LOW LINE
FE4F ﹏ WAVY LOW LINE
FF3F _ FULLWIDTH LOW LINE
Это еще один способ преобразовать только первый символ строки в верхний регистр:
"striNG".sub(/./,&:upcase)
=> "StriNG"