루비에서 문자열의 첫 글자를 대문자로 쓰는 방법


134

upcase방법은 전체 문자열을 대문자로 표시하지만 첫 글자 만 대문자로 바꿔야합니다.

또한 독일어와 러시아어와 같은 몇 가지 인기있는 언어를 지원해야합니다.

어떻게합니까?


4
일부 언어는 첫 글자를 대문자로하는 것에 대해 다른 아이디어를 가지고 있습니다. 아일랜드어에서는 "i mBaile Átha Cliath"( "더블린")-소문자 '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

답변:


260

사용하는 Ruby 버전에 따라 다릅니다.

루비 2.4 이상 :

Ruby v2.4.0 이 유니 코드 대소 문자 매핑을 지원하기 때문에 작동 합니다.

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

루비 2.3 이하 :

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

문제는 원하는 것을하지 않고 мария대신 출력 합니다 Мария.

Rails를 사용하는 경우 쉬운 해결 방법이 있습니다.

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

그렇지 않으면 유니 코드 젬 을 설치하고 다음과 같이 사용해야합니다.

require 'unicode'

Unicode::capitalize("мария") #=> Мария

루비 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".capitalize생산할 예정 My 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
순수한 루비 솔루션에 대한 찬성. 불 너무 게으른 적절한 레일,이 트릭을 :) 한
illbzo1

19

불행히도, 기계가 제대로 대문자 / 소문자 / 자본을 작성하는 것은 불가능합니다. 컴퓨터가 이해하기에는 너무 많은 상황 정보가 필요합니다.

루비의 이유 String클래스는 ASCII 문자에 대한 대문자를 지원은 적어도이 있기 때문에, 어느 정도 잘 정의.

"컨텍스트 정보"란 무엇을 의미합니까?

예를 들어, 대문자를 i올바르게 사용하려면 텍스트의 언어가 무엇인지 알아야합니다. 예를 들어 영어 에는 점이없는 i대문자 와 점이있는 I작은 대문자 만 i있습니다. 그러나 터키어에는 점이없는 i자본 I, 점이있는 자본 İ, 점이 ı없는 작은 점, 점이있는 작은 4 개의 i점이 있습니다. 그래서 영어 'i'.upcase # => 'I'와 터키어로 'i'.upcase # => 'İ'. 다시 말해 'i'.upcase, 언어에 따라 두 가지 다른 결과를 반환 할 수 있기 때문에 언어를 몰라도 단어를 올바르게 대문자로 표기하는 것은 불가능합니다.

그러나 루비는 언어를 모르고 인코딩 만 알고 있습니다. 따라서 Ruby의 내장 기능으로 문자열을 올바르게 대문자로 지정할 수 없습니다.

언어 아는 경우 에도 대문자를 올바르게 사용하는 것이 불가능한 경우가 있습니다. 예를 들어 독일어에서 'Maße'.upcase # => 'MASSE'( Maße 는 복수의 Maß 의미 측정 )입니다. 그러나 'Masse'.upcase # => 'MASSE'( 질량을 의미 ). 그래서 무엇 'MASSE'.capitalize입니까? 다시 말해, 정확하게 대문자를 사용하려면 완전한 인공 지능이 필요합니다.

따라서 루비는 때때로 잘못된 대답을하는 대신 때때로 전혀 대답 하지 않기로하므로 ASCII가 아닌 문자는 소문자 / 대문자 / 자본 작업에서 무시됩니다. (물론 잘못된 결과를 읽지 만 확인하기는 쉽습니다.)


4
미안하지만 당신의 주장에는 물이 들어 있지 않습니다. 루비가 전혀 대답을하지 않기로 선택하는 것은 사실이 아니며, 루비는 항상 잘못된 답변을 제공합니다. 예를 들어 "мария". 대소 문자는 절대로 "мария"를 반환하지 않아야합니다. 어떤 상황에서도 정확하지 않습니다. AI의 필요성에 대한 귀하의 의견은 전혀 관련이 없습니다.-대문자를 'i'에 대해 ''I ','İ ']와 같이 배열을 복원하는 것을 막을 수있는 것은 없습니다. 주어진 상황에서. 현재 루비의 대문자와 소문자 변환 처리가 중단되었습니다.
michau

2
수도 Eszett 가 있기 때문에 -1 입니다. 완전히 공식화되지 않은 일부 영역을 사용하면 AI에서만 가능한 솔루션의 증거로 사용할 수 없습니다.
Mike

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

나는이 솔루션의 내부 3 줄을 대체하여 단어의 첫 글자를 대문자로 쓰는 간단한 방법을 보여주었습니다 word. 변수 를 사용하여 분명히했습니다 . 물론, 더 많은 단어가 있다면, 그들 모두에게 전화하십시오! ;)words.map{|word| word[0] = word[0].upcase}
David

@ 데이빗. 코드는 금액 #capitalize!이 아니라 #capitalize. 후자는 새로운 String을 리턴하고 전자는 메소드의 수신자를 수정합니다 (이 경우 수신자는 word메소드입니다 #[]). #collect 블록 내에서 코드를 사용했다면 각각 동일한 String 객체를 가진 두 개의 다른 배열로 끝날 것입니다 (그리고 String은 수정되었을 것입니다). 그것은 당신이 일반적으로하고 싶은 것이 아닙니다. 이것을 알고 있더라도 다른 독자들은 이것을 이해해야합니다.
Huliax

8

레일 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 : New upcase_first Method "를 확인하십시오.


3

사용하십시오 capitalize. 로부터 문자열 문서 :

첫 번째 문자가 대문자로 변환되고 나머지는 소문자로 변환 된 str의 사본을 리턴합니다.

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

원래 문자열을 변경하려면 느낌표 만 사용하십시오.
Magnar

DOH 감사합니다, 내 실수를 수정했습니다.
jhwist

5
-1. OP 는 독일어 및 러시아어 텍스트를 명시 적으로 언급하며 ASCII가 아닌 문자를 의미합니다. String#upcase(및 String#downcase)는 ASCII 문자에 대해서만 정의됩니다.
Jörg W Mittag

1
오늘 Ruby 2.5.0을 사용하면 String#upcaseASCII가 아닌 문자에서 제대로 작동하는 것 같습니다. 2.5.0 :001 > "мария".upcase => "МАРИЯ"
Huliax

1
@Huliax 허용 된 답변에서 언급했듯이 Ruby 2.4.0 (2016 년에 릴리스 됨) 이후에만 해당됩니다.
nisetama

2

사용할 수 있습니다 mb_chars. 이것은 umlaute를 존중합니다.

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:]]합니다. upcase, downcase, capitalize, 및 swapcase2016 년 출시 된 루비 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.