取一个字符串,只大写超过三个字符的单词,除非它在开头



当我输入"战争与和平"时,我想要"战争与和平"。这个想法是采用一个字符串并使其看起来像标题或电影标题一样。将字符串中的所有单词大写,除非单词等于或小于 3 且不在开头。

当我运行此代码时:

def titleize(string)
string.split(" ").take(1).join.capitalize
string.split(" ").map do |x|
x.capitalize! if x.length > 3
end.join(" ")
end

它只返回"和平"。

试试这个:

title = 'war and peace'
def titleize(input)
input.split(' ').map.with_index { |word, index|
index == 0 || word.length > 3 ? word.capitalize : word
}.join(' ')
end

titleize title
=> "War and Peace"

你只返回"和平"的原因是因为map

为自身的每个元素调用给定块一次。

创建一个包含块返回的值的新数组。

当你做x.capitalize! if x.length > 3,你返回nil如果length <= 3

"war" if "war".length > 3
# => nil

因此,要完成这项工作,您需要确保为传递给块的每个单词返回一些内容

def titleize(string)
string.capitalize.split.map do |x|
x.length > 3 ? x.capitalize : x
end.join(" ")
end
puts titleize("war and peace") # => "War and Peace"

另外,请注意capitalize!

通过将第一个字符转换为大写,将其余字符转换为小写来修改 str。如果未进行任何更改,则返回 nil。

capitalize

返回 str 的副本,其中第一个字符转换为大写,其余字符转换为小写。

所以x.capitalize!也可以返回nil

"Peace".capitalize!
=> nil

无需将字符串转换为单词数组,将具有三个以上字符的单词大写,将它们重新连接成字符串并大写结果字符串的第一个字符。此外,这将剥夺多余的空间,这可能是不希望的。

相反,可以简单地将 String#gsub 与正则表达式一起使用来进行替换。

r = /
A               # match the start of the string
p{Lower}        # match a lowercase letter
|                # or
(?<=[ ])         # match a space in a positive lookbehind
p{Lower}        # match a lowercase letter
(?=p{Alpha}{3}) # match 3 letters in a positive lookahead 
/x               # free-spacing regex definition mode
str = "now is the    time for something to happen."
str.gsub(r) { |c| c.upcase }
#=> "Now is the    Time for Something to Happen."

正则表达式是按惯例编写的

/Ap{Lower}|(?<= )p{Lower}(?=p{Alpha}{3})/

我使用p{Lower}而不是p{Alpha}来避免不必要的大写。

请注意,在自由间距模式下,正后视中的空格包含在字符类 ((?<=[ ])( 中。这是因为自由间距模式会剥离所有不受保护的空间。

我会将字符串拆分为一个字符串数组,如下所示:

string.split(' ')

然后,如果给定字符串的长度大于 3,则每个字母大写:

for i in string.length
if string[i].length > 3 
string[i].capitalize

现在只需连接字符串:

string.join(' ')
end

尝试:

def titleize(string)
string.split.map.with_index {|x,i| if (i == 0 || x.length > 3) then x.capitalize else x end }.join(' ')
end

请注意,这不会修改传入的字符串,但您可以执行以下操作

foo = 'war and peace'
foo = titleize foo
puts foo
War and Peace

最新更新