2015-08-01 2 views
1

У меня есть следующий текст:Возвращаясь частоту слов

Grier et al. (1983) reported father and 2 sons with typical Aarskog 
syndrome, including short stature, hypertelorism, and shawl scrotum. 
They tabulated the findings in 82 previous cases. X-linked recessive 
inheritance has repeatedly been suggested (see 305400). The family 
reported by Welch (1974) had affected males in 3 consecutive 
generations. Thus, there is either genetic heterogeneity or this is an 
autosomal dominant with strong sex-influence and possibly ascertainment 
bias resulting from use of the shawl scrotum as a main criterion. 
Stretchable skin was present in the cases of Grier et al. (1983). 

Я пытаюсь вернуть список слов в тексте выше.

я сделал что-то следующим образом:

input_file.read.downcase.scan(/\b[a-z]\b/) {|word| frequency[word] = frequency[word] + 1} 

Я получаю письма (т.е. a, b, c, ..., z) и их частота в документе, а не слова. Почему это? И как я могу получить слова вместо отдельных писем?

+0

Вы хотите регулярное выражение: '/ \ b [az] + \ b /' вам нужен один или несколько символов – bjhaid

+0

'input_file.read.downcase.scan (/ \ b [az] + \ b /)' –

+0

'[az]' соответствует только одному символу. –

ответ

3

http://rubular.com - отличный ресурс.

\b[a-z]\b говорит любой символ между двумя границами слов.

Если вы хотите, чтобы для нескольких символов используйте: \b[a-z]+\b

Это говорит о каких-либо один или несколько букв между двумя границами слова.

+0

Спасибо за ваш ответ. Если мы напишем «\ b [a-z] {3,16} \ b", это вернет нам только слова размером от 3 до 16, и нам не нужно «+» после [a-z]? – Simplicity

+0

@simplicity, что правильно - {x, y} означает по крайней мере x, не более y. – ppiotrowicz

1

Я хотел бы сделать это следующим образом:

text = 'Foo. (1983). Bar baz foo bar.' 
text.downcase 
# => "foo. (1983). bar baz foo bar." 

downcase складывает текст в нижний корпус, чтобы сделать его легко найти спички для слов, независимо от случая.

text.downcase.gsub(/[^a-z ]+/i, '') 
# => "foo bar baz foo bar" 

gsub(/[^a-z ]+/i, '') удаляет символы, которые не являются частью слова, как знаки препинания и цифры.

text.downcase.gsub(/[^a-z ]+/i, '').split 
# => ["foo", "bar", "baz", "foo", "bar"] 

split сломается строку в «слова», которые разделяются пробелами.

text.downcase.gsub(/[^a-z ]+/i, '').split.each_with_object(Hash.new{ |h,k| h[k] = 0}){ |w, h| h[w] += 1 } 
# => {"foo"=>2, "bar"=>2, "baz"=>1} 

each_with_object(Hash.new{ |h,k| h[k] = 0}){ |w, h| h[w] += 1 }, как пройти через массив и подсчитать частоту элементов. Hash.new{ |h,k| h[k] = 0} - как определить хэш, который автоматически создаст значения 0 для ключей, которые не существуют.

Со всем, что в виду:

text = 'Grier et al. (1983) reported father and 2 sons with typical Aarskog syndrome, including short stature, hypertelorism, and shawl scrotum. They tabulated the findings in 82 previous cases. X-linked recessive inheritance has repeatedly been suggested (see 305400). The family reported by Welch (1974) had affected males in 3 consecutive generations. Thus, there is either genetic heterogeneity or this is an autosomal dominant with strong sex-influence and possibly ascertainment bias resulting from use of the shawl scrotum as a main criterion. Stretchable skin was present in the cases of Grier et al. (1983).' 
text.downcase 
    .gsub(/[^a-z ]+/i, '') 
    .split 
    .each_with_object(Hash.new{ |h,k| h[k] = 0}){ |w, h| h[w] += 1 } 

Какие результаты в:

# => {"grier"=>2, "et"=>2, "al"=>2, "reported"=>2, "father"=>1, "and"=>3, "sons"=>1, "with"=>2, "typical"=>1, "aarskog"=>1, "syndrome"=>1, "including"=>1, "short"=>1, "stature"=>1, "hypertelorism"=>1, "shawl"=>2, "scrotum"=>2, "they"=>1, "tabulated"=>1, "the"=>4, "findings"=>1, "in"=>3, "previous"=>1, "cases"=>2, "xlinked"=>1, "recessive"=>1, "inheritance"=>1, "has"=>1, "repeatedly"=>1, "been"=>1, "suggested"=>1, "see"=>1, "family"=>1, "by"=>1, "welch"=>1, "had"=>1, "affected"=>1, "males"=>1,... 

Если вы настаиваете на использовании регулярных выражений и scan:

text.downcase 
    .scan(/\b [a-z]+ \b/x) 
    .each_with_object(Hash.new{ |h,k| h[k] = 0}){ |w, h| h[w] += 1 } 
# => {"grier"=>2, "et"=>2, "al"=>2, "reported"=>2, "father"=>1, "and"=>3, "sons"=>1, "with"=>2, "typical"=>1, "aarskog"=>1, "syndrome"=>1, "including"=>1, "short"=>1, "stature"=>1, "hypertelorism"=>1, "shawl"=>2, "scrotum"=>2, "they"=>1, "tabulated"=>1, "the"=>4, "findings"=>1, "in"=>3, "previous"=>1, "cases"=>2, "x"=>1, "linked"=>1, "recessive"=>1, "inheritance"=>1, "has"=>1, "repeatedly"=>1, "been"=>1, "suggested"=>1, "see"=>1, "family"=>1, "by"=>1, "welch"=>1, "had"=>1, "affected"=>1, ... 

Разница действительно есть что gsub().split быстрее, чем scan(/\b [a-z]+ \b/x).

Смежные вопросы