2016-05-25 10 views
0

私は、各文字列から数値を取り出し、それらのそれぞれに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 
+0

"[ask]"とリンクと "[mcve]"をお読みください。期待される成果を知る必要があります。 –

+0

ありがとうございました: – BengDai

答えて

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

'each'の代わりに' map'を使用して直接配列を取得することができます –

+0

配列を確実に印刷できるようになりましたが、 "array [0] .to_i"コンパイラは["4"]のために "未定義のメソッド' to_i 'を教えてくれます:Array(NoMethodError) "なぜこれが起こりますか? – BengDai

+0

私は答えを更新しました。 –

1

を試すことができます。この上

瞑想:gsubが変更された文字列を返すのに対し、

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!は、代わりに文字列を変更します。我々が変更された値の配列を返すようにしたいので、

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) 

自由形式のテキストを入力すると、すべての入力文字列に対して一致を作成することはできません。無限の可能性があります。文字列の作成を担当していても、文字列全体、特定の部分のみを一致させる必要はありません。試行するほど、コードが失敗する可能性が高くなります。

関連する問題