0

文字列を分割して単語を取得しようとしています..

私のコードは次のとおりです。

def words(string)
    string.downcase!
    hash_str = Hash.new
    string.split(/\W/i).each {|y| 
      if(hash_str.has_key?(y)) 
         hash_str[y] += 1
      else 
         hash_str[y] =1
      end
    }
    return hash_str
end

hash_t = words("A man, a plan, a canal -- Panama")
hash_t.each{|x,y| puts "#{x}:#{y}"}

出力は次のとおりです。

1    :5
2   a:3  
3  plan:1
4  man:1
5  canal:1
6  panama:1

私の問題は、空白もカウントされているようです。/W に空白を追加するにはどうすればよいですか?

ありがとうございました。

4

3 に答える 3

3

空白文字列のエントリは、2 つ以上の非単語文字が隣接している場所に来ています。

その"A man, a"ため、与えるスペースで分割し"A""man, a"; 次にカンマで and を与え"man"" a"次にスペースで再び""andを与え"a"ます。

を使用split(/\W+/i)すると、単語以外の文字の各文字列が単一の分割として扱われるため、期待どおりの結果が得られます。

コードパッド リンク

于 2013-01-24T10:13:54.773 に答える
2

この場合、 を使用する方が概念的により自然scanです。このユース ケースの典型的な実装は次のようになります。

def words(string)
  Hash.new(0).tap{|h| string.downcase.scan(/\w+/){|w| h[w] += 1}}
end

words("A man, a plan, a canal -- Panama").each{|x,y| puts "#{x}:#{y}"}

これは次のようになります:

a:3
man:1
plan:1
canal:1
panama:1
于 2013-01-24T10:32:43.387 に答える
1

より Ruby っぽいソリューション:

str = "A man, a plan, a canal -- Panama"
str.downcase.split(/\W+/).inject(Hash.new(0)) { |h,v| h[v] += 1; h }

=> {"plan"=>1, "a"=>3, "panama"=>1, "man"=>1, "canal"=>1}
于 2013-01-24T10:20:16.363 に答える