如何取出每个字符串中的数字?

时间:2016-05-25 16:41:01

标签: ruby

我正在尝试从每个字符串中取出一个数字并为每个字符串添加4,但编译器一直告诉我:

  

未定义的方法`捕获'为nil:NilClass(NoMethodError)

如果我没有添加match2int2代码,则输出8会显示错误消息。

期待输出:

8
23
9
14

我该如何解决这个问题?

[
    "I have 4 cucumbers",
    "I've been given 19 radishes",
    "I have 5 carrots in my hand",
    "I gots 10 zucchini!"
].each do |string|

  match = /^I have (\d) ([a-z]*)$/.match(string)
  match2 = /I've been given (\d+) ([a-z]*)$/.match(string)

  int = match.captures[0].to_i
  int += 4
  int2 = match2.captures[0].to_i
  int2 += 4

  puts int
  puts int2

end

2 个答案:

答案 0 :(得分:3)

你可以试试这个

 array = []
 [
     "I have 4 cucumbers", 
     "I've been given 19 radishes",
     "I have 5 carrots in my hand",
     "I gots 10 zucchini!"
 ].each do |string|
      array.push(string.scan(/\d+/))
 end

 new_array = array.flatten.map {|i| i.to_i}
 #=> [4, 19, 5, 10]

 new_array.map {|i| i.to_i + 4}   #if you want to add 4 to each element
 => [8, 23, 9, 14]

答案 1 :(得分:1)

您的预期输出应该是什么并不完全清楚。

默想:

ary = ["a 4 b", "a 19 b"]

ary.each do |string|
  string.gsub!(/\b\d+\b/) { |num| (num.to_i + 4).to_s }
end

ary # => ["a 8 b", "a 23 b"]

gsub!更改了一个字符串,而gsub返回更改后的字符串。不同之处在于:

ary = ["a 4 b", "a 19 b"]

new_ary = ary.map do |string|
  string.gsub(/\b\d+\b/) { |num| (num.to_i + 4).to_s }
end

ary # => ["a 4 b", "a 19 b"]
new_ary # => ["a 8 b", "a 23 b"]

请注意,each变为map,因为我们想要返回一组已更改的值,而gsub!则是gsub

在字符串中搜索数字时使用\b非常重要,否则可能会遇到影响“foo1”之类“字”内数字的误报命中问题。

如果您想在递增后仅返回值:

ary = ["a 0 b", "a 0 b 1"]

ary.map{ |a| a.scan(/\b\d+/).map{ |i| i.to_i + 4 }}  # => [[4], [4, 5]]

分解的是,这样做:

ary
.map{ |a|
  a  # => "a 0 b", "a 0 b 1"
  .scan(/\b\d+/) # => ["0"], ["0", "1"]
  .map{ |i| i.to_i + 4 } # => [4], [4, 5]
}  # => [[4], [4, 5]]

在您正在执行的代码中:

match = /^I have (\d) ([a-z]*)$/.match(string)
match2 = /I've been given (\d+) ([a-z]*)$/.match(string)

如果您正在处理自由格式文本,则无法为每个可能的传入字符串创建匹配项;有无限的可能性。即使您负责创建字符串,也不需要匹配整个字符串,只需要匹配特定部分。您尝试匹配的次数越多,代码失败的可能性就越大。