upcase
方法可以使整个字符串变成大写,但我只需要将第一个字母大写。
另外,我需要支持德语和俄语等流行语言。
我该如何实现呢?
upcase
方法可以使整个字符串变成大写,但我只需要将第一个字母大写。
另外,我需要支持德语和俄语等流行语言。
我该如何实现呢?
这取决于你使用的 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
当使用非ASCII字符时,会出现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
这样的结果,这可能是不期望的行为。因此,这个答案并没有真正回答问题,因为他只想将第一个字母转换为大写,而保持其他字母不变。 - Daniel A. R. Werner将字符串的第一个单词的首字母大写
"kirk douglas".capitalize
#=> "Kirk douglas"
将每个单词的首字母大写
在Rails中:
"kirk douglas".titleize
=> "Kirk Douglas"
或者
"kirk_douglas".titleize
=> "Kirk Douglas"
在Ruby中:
"kirk douglas".split(/ |\_|\-/).map(&:capitalize).join(" ")
#=> "Kirk Douglas"
或者
require 'active_support/core_ext'
"kirk douglas".titleize
从 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 方法" 获取更多信息。
好的,我们只需要知道如何仅大写第一个字母并保留其余部分不变,因为有时这是所需的:
['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
- Davidwords.map{|word| word[0] = word[0].upcase}
- David#capitalize!
而不是#capitalize
。后者返回一个新的字符串,而前者修改了方法的接收器(在这种情况下,接收器是word
,方法是#[]
)。如果你在#collect块中使用你的代码,那么你最终会得到两个不同的数组,每个数组中都有相同的字符串对象(并且字符串已经被修改)。这不是你通常想要做的事情。即使你知道这一点,其他读者也应该理解这一点。 - Huliax遗憾的是,机器无法正确地将单词变成大写/小写/首字母大写。计算机需要太多上下文信息才能理解。
这就是为什么 Ruby 的 String 类只支持 ASCII 字符的大小写转换,因为至少在那里它有一定程度的定义。
我所说的 "上下文信息" 是什么意思呢?
例如,要正确地将字母 i 变成大写形式,你需要知道文本所使用的语言。比如英语中只有两个字母 i:没有点的大写 I 和有点的小写 i。但土耳其语中则有四个字母 i:没有点的大写 I、有点的大写 İ、没有点的小写 ı、有点的小写 i。因此,在英语中 'i'.upcase # => 'I',而在土耳其语中 'i'.upcase # => 'İ'。换句话说,由于 'i'.upcase 可以返回两个不同的结果,取决于语言,所以在不知道单词所用语言的情况下,正确地将其首字母大写是不可能的。
而 Ruby 并不知道语言,它只知道编码。因此,使用 Ruby 内置的功能正确地将字符串首字母大写是不可能的。
更糟糕的是,即使知道了语言,有时也无法正确地进行大小写转换。例如,在德语中,'Maße'.upcase # => 'MASSE'('Maße' 是 'Maß'(意为“测量”)的复数形式)。然而,'Masse'.upcase # => 'MASSE'(意为“质量”)。那么 'MASSE'.capitalize 是什么呢?换句话说:正确的首字母大写需要一种完全发展的人工智能。
因此,Ruby选择有时不提供任何答案,而不是有时给出错误答案,这就是为什么在downcase / upcase / capitalize操作中简单地忽略非ASCII字符的原因。 (当然,这也会导致错误的结果,但至少很容易检查。)capitalize
方法。从String文档中可以得知:
返回一个字符串的副本,其中第一个字符转换为大写,其余字符转换为小写。
"hello".capitalize #=> "Hello"
"HELLO".capitalize #=> "Hello"
"123ABC".capitalize #=> "123abc"
String#upcase
(以及String#downcase
)仅适用于ASCII字符。 - Jörg W MittagString#upcase
在非 ASCII 字符上似乎可以正常工作。
2.5.0 :001 > "мария".upcase => "МАРИЯ"
- Huliaxmb_chars
。这个方法会考虑到特殊字符,例如德语中的umlaut(变音符号):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"
My version:
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
\w
无法匹配 Cyrillic 字符或带有变音符号的拉丁字符,但 [[:word:]]
可以。在 Ruby 2.4.0 发布于2016年之前,upcase
、downcase
、capitalize
和 swapcase
不适用于非 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个字符:
"最初的回答" 翻译成英文是 "Original Answer"。
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"
word[0] = word[0].upcase
这适用于所有语言,只涉及整个字符串的第一个字母。
word = "мария"
# => "мария"
word[0] = word[0].upcase
# => "М"
word
# => "Мария"
它不需要Rails或任何其他库。
['space', 'UFO', 'NASA'].collect{|w| w.capitalize} #=> ['Space', 'Ufo', 'Nasa']
- Huliax