该upcase方法将整个字符串大写,但是我只需要大写第一个字母。
另外,我需要支持几种流行的语言,例如德语和俄语。
我该怎么做?
['space', 'UFO', 'NASA'].collect{|w| w.capitalize} #=> ['Space', 'Ufo', 'Nasa']
                该upcase方法将整个字符串大写,但是我只需要大写第一个字母。
另外,我需要支持几种流行的语言,例如德语和俄语。
我该怎么做?
['space', 'UFO', 'NASA'].collect{|w| w.capitalize} #=> ['Space', 'Ufo', 'Nasa']
                Answers:
这取决于您使用的Ruby版本:
Ruby 2.4及更高版本:
由于Ruby v2.4.0支持Unicode大小写映射,因此它可以正常工作:
"мария".capitalize #=> МарияRuby 2.3及更低版本:
"maria".capitalize #=> "Maria"
"мария".capitalize #=> мария问题是,它只是不执行您想要的操作,而是输出мария而不是Мария。
如果您使用的是Rails,有一个简单的解决方法:
"мария".mb_chars.capitalize.to_s # requires ActiveSupport::Multibyte否则,您将必须安装unicode gem并像这样使用它:
require 'unicode'
Unicode::capitalize("мария") #=> МарияRuby 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"在rails之外,但仍想使用titleize方法
require 'active_support/core_ext'
"kirk douglas".titleize #or capitalize不幸的是,机器不可能正确地进行大写/小写/大写。它需要太多的上下文信息,计算机无法理解。
这就是Ruby的String类仅支持ASCII字符大写的原因,因为那里至少有一些明确的定义。
我所说的“上下文信息”是什么意思?
例如,要i正确地大写,您需要知道文本使用的语言。例如,英语只有两个is:I不带点的大写字母和带点的小字母i。但是土耳其语有四个is:大写字母I不带点,大写İ字母带点,小ı不带点,小i带点。因此,用英语'i'.upcase # => 'I'和土耳其语'i'.upcase # => 'İ'。换句话说:由于'i'.upcase可以返回两种不同的结果(取决于语言),因此在不知道其语言的情况下正确地将其大写显然是不可能的。
但是Ruby不懂语言,只懂编码。因此,使用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。后者返回一个新的String,而前者则修改该方法的接收者(在这种情况下,接收者为word,方法为#[])。如果在#collect块中使用了代码,则最终将得到两个不同的数组,每个数组中的String对象相同(并且Strings将被修改)。那不是您通常想要做的。即使您知道这一点,其他读者也应该理解这一点。
                    从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:新的upcase_first方法 ”以获取更多信息。
使用capitalize。从字符串文档中:
返回str的副本,第一个字符转换为大写,其余字符转换为小写。
"hello".capitalize    #=> "Hello"
"HELLO".capitalize    #=> "Hello"
"123ABC".capitalize   #=> "123abc"String#upcase(以及String#downcase)仅针对ASCII字符定义。
                    String#upcase似乎可以在非ASCII字符上正常工作。2.5.0 :001 > "мария".upcase => "МАРИЯ"
                    下面是将字符串中每个单词大写的另一种方法。\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:]]匹配“标点,连接器”(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"