Rubyで文字列の最初の文字を大文字にする方法


134

upcaseこの方法は、文字列全体を大文字、私は唯一の最初の文字を大文字にする必要があります。

また、ドイツ語やロシア語など、いくつかの一般的な言語をサポートする必要があります。

どうすればいいのですか?


4
一部の言語では、大文字にする最初の文字が何であるかについて異なる考えがあることに注意してください。アイルランド語では、「i mBaileÁthaCliath」(「ダブリン内」)-小文字の「m」、大文字の「B」のようなことを行います。(アイルランド人がなぜそうするのか、なぜそれが理にかなっているのかについて知りたい場合は、en.wikipedia.org / wiki / Consonant_mutation#Celtic_languagesを参照してください。)
James Moore

3
また、#capitalizeは最初の文字以外のすべての文字を小文字にすることに注意してください。 ['space', 'UFO', 'NASA'].collect{|w| w.capitalize} #=> ['Space', 'Ufo', 'Nasa']
Huliax 2015年

回答:


260

使用するRubyのバージョンによって異なります。

Ruby 2.4以降:

Ruby v2.4.0はUnicodeのケースマッピングをサポートしているため、これは正常に機能します。

"мария".capitalize #=> Мария

Ruby 2.3以下:

"maria".capitalize #=> "Maria"
"мария".capitalize #=> мария

問題は、あなたがやりたいことをしていないだけで、のмария代わりに出力することですМария

Railsを使用している場合、簡単な回避策があります。

"мария".mb_chars.capitalize.to_s # requires ActiveSupport::Multibyte

それ以外の場合は、Unicode gem をインストールして次のように使用する必要があります。

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以下」セクションも参照してください。


19
明らか"my API is great".capitalizeMy api is great望ましくない動作となる可能性があることに注意してください。したがって、最初の文字を大文字にして他の文字はそのままにしておく必要があるため、この答えは実際には質問に答えません。
Daniel AR Werner

55

文字列の最初の単語の最初の文字を大文字にします

"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

1
純粋なRubyソリューションに賛成票を投じます。Railsを適切に
起動するのが面倒

19

残念ながら、マシンが適切に大文字/小文字/大文字にすることは不可能です。コンピュータが理解するには、あまりにも多くのコンテキスト情報が必要です。

Rubyの理由ですStringクラスは、ASCII文字のみのための総額をサポートし、それは少なくともありますので、多少明確に定義されました。

「コンテキスト情報」とはどういう意味ですか?

たとえば、i適切に大文字を使用するには、テキストがどの言語であるかを知る必要があります。たとえば、英語iのsはI、ドットなしの大文字とiドット付きの小文字の2つしかありません。しかし、トルコ語には4つiのsがあります。Iドットなしの大文字İ、ドット付きの大文字、ドットıなしの小i、ドット付きの小。それで、英語'i'.upcase # => 'I'とトルコ語で'i'.upcase # => 'İ'。つまり'i'.upcase、は言語に応じて2つの異なる結果を返すことができるため、その言語を知らずに単語を正しく大文字にすることは明らかに不可能です。

しかし、Rubyは言語を認識していません。エンコーディングのみを認識しています。したがって、Rubyの組み込み機能で文字列を適切に大文字にすることはできません。

さらに悪くなります。言語知っていても適切に大文字を使用することができない場合があります。たとえば、ドイツ語では、'Maße'.upcase # => 'MASSE'Maße測定を意味するMaßの複数形です)。ただし、(質量を意味します)。それで、何ですか?つまり、正しく資本化するには、本格的な人工知能が必要です。'Masse'.upcase # => 'MASSE''MASSE'.capitalize

したがって、Rubyは時々間違った答えを出す代わりに、まったく答え出さないことを選択します。そのため、非ASCII文字は単に小文字/大文字/大文字の操作で無視されます。(もちろん、間違った結果を読み取ることもできますが、少なくとも確認するのは簡単です。)


4
申し訳ありませんが、あなたの議論は水を保持していません。Rubyがまったく答えを返さないことを選択していることは事実ではありません。Rubyは常に答えを出しますが、これはしばしば間違っています。たとえば、 "мария" .upcaseが "мария"を返すことはありません。どのコンテキストでも正しくありません。そして、AIの必要性についての余談はまったく関係ありません-配列の再大文字化を妨げるものは何もありません。たとえば、 'i'.upcaseに対して[' I '、'İ ']と言い、どの大文字化が適切かを呼び出し側に決定させます。与えられた状況で。現在、Rubyの大文字と小文字の間の変換の処理は壊れていますが、それだけです。
michau

2
-1は、資本Eszettがあるためです。一部の完全に形式化されていない領域を使用することは、そのソリューションがAIでのみ可能であることの証明として役立ちません。
マイク

15

まあ、最初の文字だけを大文字にし、残りをそのままにする方法を知っているので、それが望ましい場合もあります。

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

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

呼び出すcapitalizeと、になり["Nasa", "Mhz", "Sputnik"]ます。


私が探していたものに感謝します。見出しを「文のケース」に変換するのに役立ちます
Good Lux

2
word[0] = word[0].upcase
デビッド

@David。番号!これにより、#collectが呼び出される配列内の単語の値が変更されます。それは悪い副作用です。
Huliax

word変数を使用して明確にしたこのソリューションの内側の3行を置き換える、単語の最初の文字を大文字にする簡単な方法を示していました。もちろん、もっと多くの単語がある場合は、それらすべてにそれらを呼び出してください!;)words.map{|word| word[0] = word[0].upcase}
デビッド

@David。あなたのコードはに等しく#capitalize!なり#capitalizeます。後者は新しい文字列を返しますが、前者はメソッドのレシーバーを変更します(この場合、レシーバーwordとメソッドはです#[])。#collectブロック内でコードを使用した場合、それぞれに同じStringオブジェクトを持つ2つの異なる配列が作成されます(Stringは変更されていたでしょう)。それはあなたが通常やりたいことではありません。これを知っていても、他の読者はこれを理解する必要があります。
Huliax

8

Rails 5以降

Active SupportおよびRails 5.0.0.beta4以降、両方の方法のいずれかを使用できます:String#upcase_firstまたはActiveSupport::Inflector#upcase_first

"my API is great".upcase_first #=> "My API is great"
"мария".upcase_first           #=> "Мария"
"мария".upcase_first           #=> "Мария"
"NASA".upcase_first            #=> "NASA"
"MHz".upcase_first             #=> "MHz"
"sputnik".upcase_first         #=> "Sputnik"

詳細については、「Rails 5:新しいupcase_firstメソッド」を確認してください。


3

を使用しcapitalizeます。文字列のドキュメントから:

最初の文字を大文字に変換し、残りを小文字に変換したstrのコピーを返します。

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

元の文字列を変更する場合にのみ感嘆符を使用します。
Magnar

dohありがとう、私の間違いを修正しました。
jhwist 2010

5
-1。OP はドイツ語とロシア語のテキストに明示的に言及しており、これは非ASCII文字を意味します。String#upcase(およびString#downcase)は、ASCII文字に対してのみ定義されます。
イェルクWミッターク

1
今日Ruby 2.5.0を使用していて、String#upcaseASCII以外の文字では問題なく動作するようです。2.5.0 :001 > "мария".upcase => "МАРИЯ"
Huliax

1
@Huliax受け入れられた回答で述べられているように、それはRuby 2.4.0(2016年にリリースされた)以降にのみ当てはまります。
nisetama

2

使用できます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"

0

以下は、文字列内の各単語を大文字にする別の方法です。\wキリル文字やラテン文字と分音記号は一致しませんが、一致[[:word:]]します。upcasedowncasecapitalize、そしてswapcase2016年にリリースされたRubyの2.4.0まで非ASCII文字には適用されませんでした。

"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:]]「句読点、コネクタ」(Pc)カテゴリの10文字すべてに一致します。

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"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.