0

我试图建立一种方法,您可以将每个单词的第一个字母大写。我把它写成

def titleize(name)
   name.scan(/\w+/) { |x| x.capitalize! }
end

它只是无法正常工作。它不会大写和字母。我做了一些搜索,最终在这里找到了大写标题的答案。它被写成

def titleize(name)
   name.split(" ").each { |x| x.capitalize! }.join(" ")
end

为什么我的代码根本没有大写?如果我添加了一个 put 语句并将其写为

def titleize(name)
   name.scan(/\w+/) { |x| puts x.capitalize! }
end

它会输出带有大写字母的“hi there”,但 => 仍然只是“hi there” 我错过了什么?

4

4 回答 4

2

更正的代码:

def titleize(name)
   name.scan(/\w+/).each { |x| x.capitalize! }.join(' ')
end

p titleize("ayan roy") #=>"Ayan Roy"

让我们看看为什么你的不工作:

def titleize(name)
   name.scan(/\w+/) 
end

p titleize("ayan roy") #=>["ayan", "roy"]

现在你的线路name.scan(/\w+/) { |x| x.capitalize! }x被传递为"ayan", "roy"。现在看下面:

def titleize(name)
   name.scan(/\w+/) { |x| p x.capitalize!  } 
end

p titleize("ayan roy")

输出:

"Ayan"
"Roy"
"ayan roy"

正如String#scan所说:

扫描(模式){|匹配,...| block } → str - 如果给出了 block,scan 将返回receiver调用它的那个。两种形式都遍历 str,匹配模式(可能是正则表达式或字符串)。对于每个匹配,都会生成一个结果并将其添加到结果数组或传递给块。

于 2013-04-17T17:56:14.000 回答
2

scan返回/产生新字符串,并且永远不会修改源字符串。也许你想要gsub

def titleize(name)
  name.gsub(/\w+/) {|x| x.capitalize }
end

或者最好使用 titleize gem中可能更正确的实现。

于 2013-04-17T17:58:18.853 回答
1

您的代码不起作用,因为#scan返回String作为正则表达式结果的新对象并将它们传递给块。因此,在您的方法中,您基本上采用了这些新对象,通过调用对它们进行了变异,#capitalize!但之后从未在任何地方使用它们。

你应该这样做:

def titleize(name)
  name.scan(/\w+/).each { |x| x.capitalize! }.join(' ')
end

但这对我来说似乎更具可读性:

def titleize2(name)
  name.split(' ').each { |w| w.capitalize! }.join(' ')
end

但是请注意,这些方法不会改变传递的原始参数。

于 2013-04-17T17:36:51.400 回答
0

的块形式scan返回原始字符串,无论您在块中做什么。(我认为您可以通过直接引用它来更改块中的原始字符串,但不建议更改您正在迭代的内容。)相反,做你的split变化,而不是each, docollect后跟join

name.split(" ").collect { |x| x.capitalize }.join(" ")

这也适用于包含数字和标点符号的标题。

于 2013-04-17T17:54:27.990 回答