upcaseSposób aktywuje cały ciąg, ale muszę wykorzystać tylko pierwszą literę.
Muszę też obsługiwać kilka popularnych języków, takich jak niemiecki i rosyjski.
Jak mam to zrobić?
upcaseSposób aktywuje cały ciąg, ale muszę wykorzystać tylko pierwszą literę.
Muszę też obsługiwać kilka popularnych języków, takich jak niemiecki i rosyjski.
Jak mam to zrobić?
['space', 'UFO', 'NASA'].collect{|w| w.capitalize} #=> ['Space', 'Ufo', 'Nasa']
Odpowiedzi:
To zależy od używanej wersji Ruby:
Ruby 2.4 i nowsze:
Po prostu działa, ponieważ Ruby v2.4.0 obsługuje mapowanie wielkości liter w formacie Unicode:
"мария".capitalize #=> Мария
Ruby 2.3 i starsze:
"maria".capitalize #=> "Maria"
"мария".capitalize #=> мария
Problem w tym, że po prostu nie robi tego, czego chcesz, марияzamiast tego wyświetla Мария.
Jeśli używasz Railsów, możesz łatwo obejść ten problem:
"мария".mb_chars.capitalize.to_s # requires ActiveSupport::Multibyte
W przeciwnym razie musisz zainstalować klejnot Unicode i używać go w następujący sposób:
require 'unicode'
Unicode::capitalize("мария") #=> Мария
Ruby 1.8:
Pamiętaj, aby użyć magicznego komentarza do kodowania :
#!/usr/bin/env ruby
puts "мария".capitalize
daje invalid multibyte char (US-ASCII), podczas gdy:
#!/usr/bin/env ruby
#coding: utf-8
puts "мария".capitalize
działa bez błędów, ale zobacz także sekcję „Ruby 2.3 i starsze”, aby zobaczyć prawdziwe wielkie litery.
"my API is great".capitalizespowoduje to, My api is greatco prawdopodobnie jest niepożądanym zachowaniem. Więc ta odpowiedź tak naprawdę nie odpowiada na pytanie, ponieważ chce tylko, aby PIERWSZA litera została zamieniona na wielką, a inne nietknięte.
wielką literą pierwszego słowa ciągu
"kirk douglas".capitalize
#=> "Kirk douglas"
wielką literą każdego słowa
W szynach:
"kirk douglas".titleize
=> "Kirk Douglas"
LUB
"kirk_douglas".titleize
=> "Kirk Douglas"
W rubinie:
"kirk douglas".split(/ |\_|\-/).map(&:capitalize).join(" ")
#=> "Kirk Douglas"
poza szynami, ale nadal chcąc użyć metody titleize
require 'active_support/core_ext'
"kirk douglas".titleize #or capitalize
Niestety, maszyna nie może poprawnie zmieniać / zmniejszać / zmniejszać wielkich liter. Potrzebuje zbyt wiele informacji kontekstowych, aby komputer mógł je zrozumieć.
Dlatego Stringklasa Rubiego obsługuje tylko wielkie litery w znakach ASCII, ponieważ jest tam przynajmniej dość dobrze zdefiniowana.
Co rozumiem przez „informacje kontekstowe”?
Na przykład, aby ipoprawnie pisać wielkimi literami , musisz wiedzieć, w jakim języku jest tekst. Na przykład angielski ma tylko dwa znaki i: duże Ibez kropki i małe iz kropką. Ale turecki ma cztery is: kapitał Ibez kropki, kapitał İz kropką, mały ıbez kropki, mały iz kropką. Tak więc w języku angielskim 'i'.upcase # => 'I'i tureckim 'i'.upcase # => 'İ'. Innymi słowy: ponieważ 'i'.upcasemoże zwrócić dwa różne wyniki, w zależności od języka, oczywiście niemożliwe jest poprawne zapisanie słowa z dużej litery bez znajomości języka.
Ale Ruby nie zna języka, zna tylko kodowanie. Dlatego niemożliwe jest poprawne zapisanie wielkiej litery w ciągu z wbudowaną funkcjonalnością Rubiego.
Sytuacja pogarsza się: nawet przy znajomości języka czasami niemożliwe jest prawidłowe wpisanie wielkich liter. Na przykład w języku niemieckim 'Maße'.upcase # => 'MASSE'( Maße to liczba mnoga od pomiaru znaczenia Maß ). Jednak (oznacza masę ). Więc co to jest ? Innymi słowy: prawidłowe kapitalizowanie wymaga pełnej sztucznej inteligencji.'Masse'.upcase # => 'MASSE''MASSE'.capitalize
Tak więc, zamiast czasami daje złą odpowiedź, Ruby zdecyduje się czasami nie dają odpowiedź na wszystko , dlatego znaki spoza ASCII prostu ignorowany w downcase / konwersji małych liter / wykorzystać operacje. (Co oczywiście prowadzi do błędnych wyników, ale przynajmniej łatwo to sprawdzić.)
Cóż, tylko po to, abyśmy wiedzieli, jak skapitalizować tylko pierwszą literę, a resztę zostawić w spokoju, ponieważ czasami jest to pożądane:
['NASA', 'MHz', 'sputnik'].collect do |word|
letters = word.split('')
letters.first.upcase!
letters.join
end
=> ["NASA", "MHz", "Sputnik"]
Połączenie capitalizespowoduje ["Nasa", "Mhz", "Sputnik"].
word[0] = word[0].upcase
wordzmiennej. Oczywiście, jeśli masz więcej słów, po prostu zadzwoń do nich wszystkich! ;)words.map{|word| word[0] = word[0].upcase}
#capitalize!i nie #capitalize. Ta ostatnia zwraca nowy ciąg, podczas gdy pierwsza modyfikuje adresata metody (w tym przypadku odbiornikiem jest, worda metoda jest #[]). Jeśli użyjesz swojego kodu wewnątrz bloku #collect, otrzymasz dwie różne tablice z tymi samymi obiektami typu String w każdej z nich (a Strings zostałyby zmodyfikowane). To nie jest coś, co normalnie chciałbyś zrobić. Nawet jeśli jesteś tego świadomy, inni czytelnicy powinni to zrozumieć.
Od Active Support i Rails 5.0.0.beta4 możesz użyć jednej z dwóch metod: String#upcase_firstlub 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"
Sprawdź " Rails 5: Nowa metoda upcase_first ", aby uzyskać więcej informacji.
Użyj capitalize. Z dokumentacji String :
Zwraca kopię str z pierwszym znakiem zamienionym na wielką, a pozostałą na małą.
"hello".capitalize #=> "Hello"
"HELLO".capitalize #=> "Hello"
"123ABC".capitalize #=> "123abc"
String#upcase(a także String#downcase) są zdefiniowane tylko dla znaków ASCII.
String#upcasewydaje się, że działa dobrze na znakach spoza ASCII. 2.5.0 :001 > "мария".upcase => "МАРИЯ"
Poniżej znajduje się inny sposób zapisania każdego słowa w ciągu wielkimi literami. \wnie dopasowuje cyrylicy ani znaków łacińskich ze znakami diakrytycznymi, ale [[:word:]]tak. upcase, downcase, capitalize, I swapcasenie stosuje się do znaków spoza ASCII aż Ruby 2.4.0, która została wydana w 2016 roku.
"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:]] dopasowuje znaki z tych kategorii:
Ll (Letter, Lowercase)
Lu (Letter, Uppercase)
Lt (Letter, Titlecase)
Lo (Letter, Other)
Lm (Letter, Modifier)
Nd (Number, Decimal Digit)
Pc (Punctuation, Connector)
[[:word:]]pasuje do wszystkich 10 znaków z kategorii „Interpunkcja, łącznik” ( 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
Jest to inny sposób konwersji tylko pierwszego znaku ciągu na wielką literę:
"striNG".sub(/./,&:upcase)
=> "StriNG"
Moja wersja:
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"]
Sprawdź również:
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