Należy pamiętać, że niektóre języki mają różne wyobrażenia o tym, jaka jest pierwsza litera, która ma być wielka. W języku irlandzkim robisz takie rzeczy, jak „i mBaile Átha Cliath” („w Dublinie”) - małe litery „m”, duże litery „B”. (Zobacz en.wikipedia.org/wiki/Consonant_mutation#Celtic_languages, jeśli jesteś ciekawy, dlaczego Irish to zrobił i dlaczego ma to sens.)
James Moore,
4
Pamiętaj też, że #capitalize spowoduje zmniejszenie wszystkich liter, które nie są pierwszą literą ... co nie zawsze jest tym, czego chcesz. ['space', 'UFO', 'NASA'].collect{|w| w.capitalize} #=> ['Space', 'Ufo', 'Nasa']
Huliax
Odpowiedzi:
264
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:
Zauważ, że najwyraźniej "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.
Głosuj za czystym rozwiązaniem Ruby. Zbyt leniwy, żeby odpalić Railsy, a to
załatwiło sprawę
19
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ć.)
Przepraszam, ale twoja argumentacja nie ma sensu. Nie jest prawdą, że Ruby w ogóle nie chce udzielać odpowiedzi, Ruby zawsze daje odpowiedź, która często jest błędna - np. „Мария” .upcase nie powinien nigdy zwracać „мария”, co nie jest poprawne w żadnym kontekście. A twoje dygresje na temat potrzeby sztucznej inteligencji w ogóle nie mają znaczenia - nic nie stoi na przeszkodzie, aby zachować tablicę z użyciem wielkich liter, powiedz [„I”, „İ”] zamiast „i”. w danej sytuacji. Obecnie Ruby obsługuje konwersję między dużymi i małymi literami i to wszystko.
michau
2
-1, ponieważ istnieje duże Eszett . Wykorzystanie jakiegoś niezupełnie sformalizowanego obszaru nie może świadczyć o tym, że rozwiązanie jest możliwe tylko w przypadku AI.
Mike
17
Cóż, tylko po to, abyśmy wiedzieli, jak skapitalizować tylko pierwszą literę, a resztę zostawić w spokoju, ponieważ czasami jest to pożądane:
Dziękuję tylko tego, czego szukałem, przydatne do konwersji nagłówków na
Good Lux
2
word[0] = word[0].upcase
David
@David. NIE! To zmienia wartości słów w tablicy, do której jest wywoływana #collect. To zły efekt uboczny.
Huliax
Pokazałem prostszy sposób kapitalizacji pierwszej litery słowa, zastępując wewnętrzne 3 wiersze tego rozwiązania, co wyjaśniłem, używając wordzmiennej. Oczywiście, jeśli masz więcej słów, po prostu zadzwoń do nich wszystkich! ;)words.map{|word| word[0] = word[0].upcase}
David
@David. Twój kod jest równy #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ć.
Huliax
12
Szyny 5+
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"
Użyj wykrzyknika tylko wtedy, gdy chcesz zmienić oryginalny ciąg.
Magnar,
doh Dzięki, naprawiłem mój błąd.
jhwist
5
-1. OP wyraźnie wymienia tekst w języku niemieckim i rosyjskim, co oznacza znaki spoza ASCII. String#upcase(a także String#downcase) są zdefiniowane tylko dla znaków ASCII.
Jörg W Mittag,
1
Używam dziś Ruby 2.5.0 i String#upcasewydaje się, że działa dobrze na znakach spoza ASCII. 2.5.0 :001 > "мария".upcase => "МАРИЯ"
Huliax
1
@Huliax Jak wspomniano w zaakceptowanej odpowiedzi, tak było dopiero od czasu Ruby 2.4.0 (który został wydany w 2016 roku).
nisetama
2
Możesz użyć mb_chars. To szanuje umlaut:
classString# Only capitalize first letter of a stringdefcapitalize_firstself[0] = self[0].mb_chars.upcase
selfendend
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ę:
['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.
źródło
"my API is great".capitalize
spowoduje to,My api is great
co 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
źródło
Niestety, maszyna nie może poprawnie zmieniać / zmniejszać / zmniejszać wielkich liter. Potrzebuje zbyt wiele informacji kontekstowych, aby komputer mógł je zrozumieć.
Dlatego
String
klasa 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
i
poprawnie pisać wielkimi literami , musisz wiedzieć, w jakim języku jest tekst. Na przykład angielski ma tylko dwa znakii
: dużeI
bez kropki i małei
z kropką. Ale turecki ma czteryi
s: kapitałI
bez kropki, kapitałİ
z kropką, małyı
bez kropki, małyi
z kropką. Tak więc w języku angielskim'i'.upcase # => 'I'
i tureckim'i'.upcase # => 'İ'
. Innymi słowy: ponieważ'i'.upcase
moż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ć.)
źródło
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
capitalize
spowoduje["Nasa", "Mhz", "Sputnik"]
.źródło
word[0] = word[0].upcase
word
zmiennej. 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,word
a 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ć.Szyny 5+
Od Active Support i Rails 5.0.0.beta4 możesz użyć jednej z dwóch metod:
String#upcase_first
lubActiveSupport::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.
źródło
Użyj
capitalize
. Z dokumentacji String :"hello".capitalize #=> "Hello" "HELLO".capitalize #=> "Hello" "123ABC".capitalize #=> "123abc"
źródło
String#upcase
(a takżeString#downcase
) są zdefiniowane tylko dla znaków ASCII.String#upcase
wydaje się, że działa dobrze na znakach spoza ASCII.2.5.0 :001 > "мария".upcase => "МАРИЯ"
Możesz użyć
mb_chars
. To szanuje umlaut:class String # Only capitalize first letter of a string def capitalize_first self[0] = self[0].mb_chars.upcase self end end
Przykład:
"ümlaute".capitalize_first #=> "Ümlaute"
źródło
Poniżej znajduje się inny sposób zapisania każdego słowa w ciągu wielkimi literami.
\w
nie dopasowuje cyrylicy ani znaków łacińskich ze znakami diakrytycznymi, ale[[:word:]]
tak.upcase
,downcase
,capitalize
, Iswapcase
nie stosuje się do znaków spoza ASCII aż Ruby 2.4.0, która została wydana w 2016 roku.[[:word:]]
dopasowuje znaki z tych kategorii:[[:word:]]
pasuje do wszystkich 10 znaków z kategorii „Interpunkcja, łącznik” (Pc
):Jest to inny sposób konwersji tylko pierwszego znaku ciągu na wielką literę:
źródło
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
źródło