我正在尝试从每个字符串中取出一个数字并为每个字符串添加4,但编译器一直告诉我:
未定义的方法`捕获'为nil:NilClass(NoMethodError)
如果我没有添加match2
和int2
代码,则输出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
答案 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)
如果您正在处理自由格式文本,则无法为每个可能的传入字符串创建匹配项;有无限的可能性。即使您负责创建字符串,也不需要匹配整个字符串,只需要匹配特定部分。您尝试匹配的次数越多,代码失败的可能性就越大。