upcase
วิธีการใช้ประโยชน์สตริงทั้งหมด แต่ฉันต้องการที่จะลงทุนเพียงตัวอักษรตัวแรก
นอกจากนี้ฉันต้องรองรับภาษายอดนิยมหลายภาษาเช่นเยอรมันและรัสเซีย
ฉันต้องทำอย่างไร?
upcase
วิธีการใช้ประโยชน์สตริงทั้งหมด แต่ฉันต้องการที่จะลงทุนเพียงตัวอักษรตัวแรก
นอกจากนี้ฉันต้องรองรับภาษายอดนิยมหลายภาษาเช่นเยอรมันและรัสเซีย
ฉันต้องทำอย่างไร?
['space', 'UFO', 'NASA'].collect{|w| w.capitalize} #=> ['Space', 'Ufo', 'Nasa']
คำตอบ:
ขึ้นอยู่กับรุ่น Ruby ที่คุณใช้:
Ruby 2.4 และสูงกว่า:
มันใช้งานได้เนื่องจากRuby v2.4.0รองรับ Unicode case mapping:
"мария".capitalize #=> Мария
Ruby 2.3 และต่ำกว่า:
"maria".capitalize #=> "Maria"
"мария".capitalize #=> мария
ปัญหาคือมันก็ไม่ได้ทำในสิ่งที่คุณต้องการให้มันจะออกผลลัพธ์แทนмария
Мария
หากคุณใช้ Rails มีวิธีแก้ปัญหาง่ายๆ:
"мария".mb_chars.capitalize.to_s # requires ActiveSupport::Multibyte
มิฉะนั้นคุณจะต้องติดตั้งUnicode gem และใช้งานในลักษณะนี้:
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 และต่ำกว่า" สำหรับการใช้อักษรตัวพิมพ์ใหญ่จริง
"my API is great".capitalize
จะก่อให้เกิดMy api is great
พฤติกรรมที่ไม่พึงปรารถนา ดังนั้นคำตอบนี้ไม่ได้ตอบคำถามอย่างแท้จริงเนื่องจากเขาต้องการให้ตัวอักษร FIRST เปลี่ยนเป็นตัวพิมพ์ใหญ่และอื่น ๆ โดยไม่ถูกแตะต้อง
อักษรตัวแรกของคำแรกของสตริงเป็นตัวพิมพ์ใหญ่
"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
น่าเสียดายที่เป็นไปไม่ได้ที่เครื่องจะขึ้น / ลง / ใช้ตัวพิมพ์ใหญ่ มันต้องการข้อมูลเชิงบริบทมากเกินไปสำหรับคอมพิวเตอร์ที่จะเข้าใจ
นั่นเป็นเหตุผลที่String
คลาสของ Ruby รองรับเฉพาะอักษรตัวพิมพ์ใหญ่สำหรับอักขระ ASCII เนื่องจากอย่างน้อยก็มีการกำหนดไว้อย่างดี
"ข้อมูลบริบท" หมายถึงอะไร
ตัวอย่างเช่นในการใช้อักษรตัวพิมพ์ใหญ่i
อย่างถูกต้องคุณจำเป็นต้องทราบว่าข้อความนั้นอยู่ในภาษาใดตัวอย่างเช่นภาษาอังกฤษมีเพียงสองi
s: capital ที่I
ไม่มีจุดและขนาดเล็กที่i
มีจุด แต่ภาษาตุรกีมีสี่i
s: capital I
without a dot, capital İ
with a dot, small ı
without a dot, small i
with a dot ดังนั้นในภาษาอังกฤษและตุรกี'i'.upcase # => 'I'
'i'.upcase # => 'İ'
กล่าวอีกนัยหนึ่ง: เนื่องจาก'i'.upcase
สามารถส่งคืนผลลัพธ์ที่แตกต่างกันสองรายการขึ้นอยู่กับภาษาจึงเป็นไปไม่ได้ที่จะใช้อักษรตัวพิมพ์ใหญ่อย่างถูกต้องโดยไม่ต้องรู้ภาษา
แต่รูบี้ไม่รู้ภาษารู้แค่การเข้ารหัสเท่านั้น ดังนั้นจึงเป็นไปไม่ได้ที่จะใช้ประโยชน์จากสตริงอย่างถูกต้องด้วยฟังก์ชันในตัวของ Ruby
จะได้รับแย่: แม้จะมีการรู้ภาษาที่บางครั้งก็เป็นไปไม่ได้ที่จะทำเงินทุนของ บริษัท อย่างถูกต้อง ตัวอย่างเช่นในภาษาเยอรมัน'Maße'.upcase # => 'MASSE'
( Maßeเป็นพหูพจน์ของการวัดความหมายของMaß ) อย่างไรก็ตาม(หมายถึงมวล ) แล้วคืออะไร? กล่าวอีกนัยหนึ่ง: การใช้อักษรตัวพิมพ์ใหญ่อย่างถูกต้องจำเป็นต้องใช้ปัญญาประดิษฐ์เต็มรูปแบบ'Masse'.upcase # => 'MASSE'
'MASSE'.capitalize
ดังนั้นแทนที่จะบางครั้งการให้คำตอบที่ผิดทับทิมเลือกที่จะให้บางครั้งไม่มีคำตอบที่ทุกคนซึ่งเป็นเหตุผลที่อักขระที่ไม่ใช่ ASCII เพียงแค่ได้รับการละเว้นใน downcase / upcase / ประโยชน์การดำเนินงาน (ซึ่งแน่นอนว่าอ่านผลลัพธ์ผิดด้วย แต่อย่างน้อยก็ตรวจสอบได้ง่าย)
ดังนั้นเราจึงรู้วิธีใช้ตัวพิมพ์ใหญ่เพียงตัวอักษรตัวแรกและปล่อยให้ส่วนที่เหลืออยู่คนเดียวเพราะบางครั้งนั่นคือสิ่งที่ต้องการ:
['NASA', 'MHz', 'sputnik'].collect do |word|
letters = word.split('')
letters.first.upcase!
letters.join
end
=> ["NASA", "MHz", "Sputnik"]
โทรจะส่งผลให้capitalize
["Nasa", "Mhz", "Sputnik"]
word[0] = word[0].upcase
word
ตัวแปร แน่นอนว่าหากคุณมีคำศัพท์มากกว่านี้ก็เพียงแค่เรียกพวกเขาทั้งหมด! ;)words.map{|word| word[0] = word[0].upcase}
#capitalize!
#capitalize
ส่วนหลังส่งคืนสตริงใหม่ในขณะที่อดีตปรับเปลี่ยนผู้รับของวิธีการ (ในกรณีนี้คือตัวรับword
และวิธีการคือ#[]
) หากคุณใช้รหัสของคุณภายในบล็อก #collect คุณจะได้อาร์เรย์สองอาร์เรย์ที่แตกต่างกันโดยมีอ็อบเจ็กต์ String เดียวกันในแต่ละอาร์เรย์ (และสตริงจะได้รับการแก้ไข) นั่นไม่ใช่สิ่งที่คุณต้องการทำตามปกติ แม้ว่าคุณจะทราบเรื่องนี้ แต่ผู้อ่านคนอื่น ๆ ก็ควรเข้าใจสิ่งนี้
ในขณะที่ 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 " สำหรับข้อมูลเพิ่มเติม
ใช้capitalize
. จากเอกสารString :
ส่งคืนสำเนาของ str ที่มีอักขระตัวแรกที่แปลงเป็นตัวพิมพ์ใหญ่และส่วนที่เหลือเป็นตัวพิมพ์เล็ก
"hello".capitalize #=> "Hello"
"HELLO".capitalize #=> "Hello"
"123ABC".capitalize #=> "123abc"
String#upcase
(และString#downcase
) กำหนดไว้สำหรับอักขระ ASCII เท่านั้น
String#upcase
ดูเหมือนว่าจะทำงานได้ดีกับอักขระที่ไม่ใช่ ASCII 2.5.0 :001 > "мария".upcase => "МАРИЯ"
คุณสามารถใช้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"
ด้านล่างนี้เป็นอีกวิธีหนึ่งในการใช้ตัวพิมพ์ใหญ่ในแต่ละคำในสตริง \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"
เวอร์ชันของฉัน:
class String
def upcase_first
return self if empty?
dup.tap {|s| s[0] = s[0].upcase }
end
def upcase_first!
replace upcase_first
end
end
['NASA title', 'MHz', 'sputnik'].map &:upcase_first #=> ["NASA title", "MHz", "Sputnik"]
ตรวจสอบด้วย:
https://www.rubydoc.info/gems/activesupport/5.0.0.1/String%3Aupcase_first
https://www.rubydoc.info/gems/activesupport/5.0.0.1/ActiveSupport/Inflector#upcase_first-instance_method