当我作为输入进入时,"战争与和平",我想要"战争与和平"。我们的想法是获取一个字符串并使其显示为标题或电影标题。大写字符串中的所有单词,除非单词等于或小于3而不是在开头。
当我运行此代码时:
def titleize(string)
string.split(" ").take(1).join.capitalize
string.split(" ").map do |x|
x.capitalize! if x.length > 3
end.join(" ")
end
仅返回"和平"
答案 0 :(得分:2)
试试这个:
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"
答案 1 :(得分:2)
你之所以回归和平'是因为map
为self的每个元素调用给定的块一次。
创建一个包含块返回值的新数组。
执行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。
返回str的副本,第一个字符转换为大写,余数为小写。
所以x.capitalize!
也可以返回nil
"Peace".capitalize!
=> nil
答案 2 :(得分:2)
无需将字符串转换为单词数组,将具有三个以上字符的单词大写,将它们连接回字符串并将结果字符串的第一个字符大写。此外,这将剥夺额外的空间,这可能是不希望的。
相反,可以简单地使用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."
正则表达式通常是
/\A\p{Lower}|(?<= )\p{Lower}(?=\p{Alpha}{3})/
我使用\p{Lower}
而不是\p{Alpha}
来避免不必要的大写。
请注意,在自由间隔模式下,正向后观的空间包含在字符类((?<=[ ])
)中。这是因为自由间隔模式剥离了所有不受保护的空间。
答案 3 :(得分:0)
我会将字符串拆分成一个字符串数组,如下所示:
string.split(' ')
如果给定字符串的长度大于3,则将每个第一个字母大写:
for i in string.length
if string[i].length > 3
string[i].capitalize
现在加入字符串:
string.join(' ')
end
答案 4 :(得分:0)
尝试:
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