文字列の最初の文字のみを大文字にし、他の文字はそのままにしますか?(レール)


102

Railsで文字列の最初の文字を大文字にし、他の文字はすべてそのままにしようとしています。「私はニューヨーク出身」が「私はニューヨーク出身」に変わるという問題に遭遇しています。

最初の文字を選択するにはどの方法を使用しますか?

ありがとう

編集: macekが提案したものを実装しようとしましたが、「未定義のメソッド「大文字」」エラーが発生します。コードは、capitalize行がなくても正常に動作します。助けてくれてありがとう!

def fixlistname!
  self.title = self.title.lstrip + (title.ends_with?("...") ? "" : "...")
  self.title[0] = self.title[0].capitalize
  errors.add_to_base("Title must start with \"You know you...\"") unless self.title.starts_with? 'You know you'
end

編集2:うまくいきました。助けてくれてありがとう!

編集3:待って、いいえ、私はしませんでした...これが私のリストモデルの内容です。

def fixlistname!
  self.title = self.title.lstrip + (title.ends_with?("...") ? "" : "...")
  self.title.slice(0,1).capitalize + self.title.slice(1..-1)
  errors.add_to_base("Title must start with \"You know you...\"") unless self.title.starts_with?  'You know you'
end

編集4: macekの編集を試みましたが、未定義のメソッド「capitalize」エラーが発生します。何が問題でしょうか?

def fixlistname!
  self.title = title.lstrip
  self.title += '...' unless title.ends_with?('...')
  self.title[0] = title[0].capitalize
  errors.add_to_base('Title must start with "You know you..."') unless title.starts_with?("You know you")
end

編集5:これは奇妙です。以下の行を使用して、未定義のメソッドエラーを取り除くことができます。問題は、最初の文字を数字に置き換えているように見えることです。たとえば、Youyを大文字にする代わりに、yを121に変換します

self.title[0] = title[0].to_s.capitalize

に基づいてEDIT 3、2行目をで始める必要がありますself.title = 。また、3行すべてself.titleで、=(等号)の左側のみが必要です。他の場所ではそのまま使用できますtitle。例については、私の回答の編集を参照してください。
マセック

2
Edit4の問題は、文字だけではなく文字列しか得られないことです。そのため、文字列関数の「大文字」を認識できません。
Taryn East、

Edit 5の問題は、title [0]がfixnumであることです。したがって、title [0] .to_sを呼び出すと、文字番号(つまり、121を文字列として: "121")が得られます。必要に応じて、self.title [0] = title.first.capitalizeを実行できます。
Nick

#upcase_first_caseを追加してプルリクエストを行いました:github.com/rails/rails/pull/15319。フィードバックを自由に追加してください。
Aldo 'xoen' Giambelluca '25年

回答:


93

Titleizeはすべての単語を大文字にします。この行は重く感じられますが、変更された唯一の文字が最初の文字であることを保証します。

new_string = string.slice(0,1).capitalize + string.slice(1..-1)

更新:

irb(main):001:0> string = "i'm from New York..."
=> "i'm from New York..."
irb(main):002:0> new_string = string.slice(0,1).capitalize + string.slice(1..-1)
=> "I'm from New York..."

まだ動作していません。誤警報:/私はそれを間違って実装しているだけだと思います。
ダニエル・オコナー

1
ダニエル-あなたの問題を解決した答えを「受け入れる」ことは、一般的に良い形です。答えの左側にある「チェックマーク」をクリックしてこれを行うことができます。:)
タリンイースト

1
私は質問を誤解しました、さもなければ私はあなたに1アップを与えたかったです。.capitalizeではなく.titleizeを探していました。とにかくタリン、ありがとう!
Eric Wanchic 2014年

OOC-なぜあなたは賛成票を与えるのを止めるのですか?元の投稿者の質問に正しく答えましたか?あなたがそう思うなら-賛成票を投じてください。それは他のものに依存する必要はありません... :)
Taryn East

2
だから、ここに行きます: s[0].capitalize + s[1..-1] if s.present?
アレックスエスカランテ2016年

126

これはそれを行うはずです:

title = "test test"     
title[0] = title[0].capitalize
puts title # "Test test"

40
またはより簡潔に、title[0] = title[0].capitalize
ジョン・ガービン

これは非常にエレガントなソリューションです。
カリュー

1
@JonGarvin title [0] .capitalizeは機能しません(少なくともRuby 1.8.7では)。title[0]はFixnumを返し、capitalizeは文字列を期待するため、title.first.capitalizeは行く。
Nick

2
恥ずかしいことtitle.first.capitalize!
アダムウェイト

1
capitalize最初の文字の後のすべての文字を小文字に変換するため、質問で提示された文字列(「i'm from New York」)では機能しません。
マークシュナイダー、

57

あなたは人間化を使うことができます。テキスト行にアンダースコアや他の大文字が必要ない場合。

入力:

"i'm from New_York...".humanize

出力:

"I'm from new york..."

7
OPは特に「ニューヨーク」を避けたかった
ファットマン

確かに、私の答えでは少し速すぎます。
Bartuzz 2013年

17
@BartuzzこれはOPが望んでいたものではありませんが、まさに私が探していたものです。ありがとう!
Yetti、2014

ただし、ニューヨークは固有名詞であるため文法に反し、大文字を使用する必要があります。
Shayne、

警告さhumanizeれるのはRailsであり、まさにActiveSupportメソッドです。普通のルビーではそれはできません。
ペンギン

51
str = "this is a Test"
str.sub(/^./, &:upcase)
# => "This is a Test"

1
簡潔でエレガント。これが一番の答えだと思います。
クリス

同意する。これは受け入れられる答えだと思います。
Garry Pettet

一つの癖は、なので^、行の始めを意味し、に"\nfoo"なり"\nFoo"ます。ほとんどの場合、それで十分でしょう。これsubはa gsubではなくa であるため、複数行の文字列であっても、1文字だけ大文字になります。
Henrik N

を使用して上記の制限を取得できます。これによりstr.sub(/\S/, &:upcase)、最初の非空白文字が検出され、大文字に変換されます。
Anthony Panozzo、

39

以下のようRailsの5.0.0.beta4新しい使用することができるString#upcase_first方法をかActiveSupport::Inflector#upcase_firstそれをします。詳細については、このブログ投稿を確認してください。


それは素晴らしいニュースです!私たちが今何ができるかを考えていました。おそらくRails 4のポリフィルがいいでしょう。
hakunin

mb_charsを使用しても、upcase_firstはアクセント/特殊文字を処理しないことに注意してください
user3033467

14

オブジェクト指向のソリューション:

class String
  def capitalize_first_char
    self.sub(/^(.)/) { $1.capitalize }
  end
end

次に、これを行うことができます:

"i'm from New York".capitalize_first_char

少なくとも誰かがStringクラスの拡張でエレガントなソリューションを書いた。
Dmitriy 2013

@Dmitriyなぜサルは文字列クラスにエレガントなパッチを適用するのですか?
Gerard Simpson、


6

編集2

あなたの問題を再現することはできません。このネイティブRubyスクリプトを実行してください。それはあなたが探している正確な出力を生成し、Railsはこれらすべてのメソッドをサポートしています。どのような入力で問題がありますか?

#!/usr/bin/ruby
def fixlistname(title)
  title = title.lstrip
  title += '...' unless title =~ /\.{3}$/
  title[0] = title[0].capitalize
  raise 'Title must start with "You know you..."' unless title =~ /^You know you/
  title
end

DATA.each do |title|
  puts fixlistname(title)
end

__END__
you know you something WITH dots ...
you know you something WITHOUT the dots
  you know you something with LEADING whitespace...
  you know you something with whitespace BUT NO DOTS
this generates error because it doesn't start with you know you

出力

You know you something WITH dots ...
You know you something WITHOUT the dots...
You know you something with LEADING whitespace...
You know you something with whitespace BUT NO DOTS...
RuntimeError: Title must start with "You know you..."

編集する

編集に基づいて、次のようなことを試すことができます。

def fixlistname!
  self.title = title.lstrip
  self.title += '...' unless title.ends_with?('...')
  self.title[0] = title[0].capitalize
  errors.add_to_base('Title must start with "You know you..."') unless title.starts_with?("You know you")
end

元の

これはトリックを行います

s = "i'm from New York"
s[0] = s[0].capitalize
#=> I'm from New York

String#capitalize文字列全体で使用しようとするI'm from new yorkと、メソッドが次の理由で表示されていました。

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

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

+1原因PCで試してみるまではうまくいくとは思いませんでした:)
Jeriko 2010

こんにちは、助けてくれてありがとう。私は何を間違っているのですか?元の質問を編集して自分のコードを含めました。
ダニエル・オコナー

私はタリンの提案を使用して、それを機能させました。助けてくれてありがとう!
ダニエル・オコナー、

こんにちは、stackoverflowはあなたが編集を行ったと言っていますが、私は何も変わっていませんか?
ダニエル・オコナー


4

これらの回答のほとんどは、文字列を適切に編集します。ビューの出力をフォーマットするだけの場合は、基になる文字列を変更したくないため、編集したコピーを取得するためtapにaの後に使用できdupます。

'test'.dup.tap { |string| string[0] = string[0].upcase }

3

OPがStringオブジェクトにサルのパッチを適用する場合にのみ、これを使用できます

class String
  # Only capitalize first letter of a string
  def capitalize_first
    self.sub(/\S/, &:upcase)
  end
end

今それを使用してください:

"i live in New York".capitalize_first #=> I live in New York

2

さらに短いバージョンは次のようになります:

s = "i'm from New York..."
s[0] = s.capitalize[0]

2

これを簡潔に行うことができる、誰も言及していないgsub。

string.gsub(/^([a-z])/) { $1.capitalize }

例:

 > 'caps lock must go'.gsub(/^(.)/) { $1.capitalize }
=> "Caps lock must go"


1

マルチバイト文字を処理する必要がある場合、つまり、サイトを国際化する必要がある場合、s[0] = ...ソリューションは適切ではないことに注意してください。このスタックオーバーフローの質問は、unicode-util gemの使用を提案しています

Ruby 1.9:マルチバイト文字列を適切に大文字または小文字にするにはどうすればよいですか?

編集する

実際には、少なくとも奇妙な文字列エンコーディングを回避する簡単な方法は、String#mb_charsを使用することです

s = s.mb_chars
s[0] = s.first.upcase
s.to_s

0

文字列のメソッドを分類するのはどうですか?

'somESTRIng'.classify

出力:

#rails => 'SomESTRIng'

1
単語を単数形にするなど、多くの追加機能を実行しています。"hello worlds".classify # => "Hello world"
Pavel Pravosud、2014年

-3
string = "i'm from New York"
string.split(/\s+/).each{ |word,i| word.capitalize! unless i > 0 }.join(' ')
# => I'm from New York

そうそう。私はルビーは初めてですが、他の答えは実際にはOPが要求したことを実行しなかったので、それを機能させました:D間違っている場合は修正してください。多くの言語で働きますか?
ジェリコ

3
これはRuby固有の質問です。string[i]が他の言語で機能しなくても問題ありません。StackOverflowがこのようなハッキングされた答えを散らかさないようにしてください。私たちはRTFMを言うことはできませんが、でも、迅速で一目String...ドキュメントを回避するには、このような答えを助けただろう
マセック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.