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

问题描述 投票:0回答:5

当我输入“战争与和平”时,我想要“战争与和平”。我们的想法是获取一个字符串并使其显示为标题或电影标题。大写字符串中的所有单词,除非单词等于或小于3而不是在开头。

当我运行此代码时:

def titleize(string)
      string.split(" ").take(1).join.capitalize
      string.split(" ").map do |x|

        x.capitalize! if x.length > 3

      end.join(" ")
end

它只返回“和平”。

ruby string
5个回答
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"

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。

capitalize

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

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

"Peace".capitalize!
=> nil

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}来避免不必要的大写。

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


0
投票

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

string.split(' ')

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

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

现在加入字符串:

  string.join(' ')
end

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
© www.soinside.com 2019 - 2024. All rights reserved.