Заглавная буква в рубине

Метод upcase использует всю строку в целом.

Мне нужно загладить только первую букву.

Кроме того, мне нужно поддерживать несколько популярных языков, таких как немецкий и русский.

Как мне это сделать?

Ответ 1

Это зависит от используемой вами версии 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 и нижний раздел для реальной заглавной буквы.

Ответ 2

заглавная буква первой строки строки

"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

Ответ 3

К сожалению, невозможно, чтобы машина правильно вставила/опущена/заглавная буква. Для понимания этого компьютера требуется слишком много контекстуальной информации.

Итак, почему класс 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. (Который, конечно, также читает неверные результаты, но, по крайней мере, легко проверить.)

Ответ 4

Ну, просто, чтобы мы знали, как использовать только первую букву и оставить их в покое (потому что иногда это то, что нужно)...

['NASA', 'MHz', 'sputnik'].collect do |word|
  letters = word.split('')
  letters.first.upcase!
  letters.join
end

 => ["NASA", "MHz", "Sputnik"]

Вызов #capitalize приведет к ["Nasa", "Mhz", "Sputnik"]

Ответ 5

В Active Directory и Rails 5.0.0.beta4 вы можете использовать один из двух методов: String#upcase_first или ActiveSupport::Inflector#upcase_first. Подробнее см. сообщение в блоге.

Ответ 6

Используйте capitalize. Из docs:

Возвращает копию str с первым символом, преобразованным в верхний регистр, а остальное - в нижний регистр.

      "hello".capitalize    #=> "Hello"
      "HELLO".capitalize    #=> "Hello"
      "123ABC".capitalize   #=> "123abc"

Ответ 7

Вы можете использовать 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"

Ответ 8

Ниже приведен еще один способ использовать каждое слово в строке. \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"