Количество слов в Rails? - PullRequest
       2

Количество слов в Rails?

16 голосов
/ 21 января 2010

Скажем, у меня есть модель блога с названием и телом. Как мне показать количество слов в теле и символов в заголовке? Я хочу, чтобы на выходе было что-то вроде этого

Название: Lorem Тело: Lorem Lorem Lorem

Количество сообщений в этом сообщении равно 3.

Ответы [ 6 ]

34 голосов
/ 21 января 2010
"Lorem Lorem Lorem".scan(/\w+/).size
=> 3

ОБНОВЛЕНИЕ : если вам нужно сопоставить рок-н-ролл как одно слово, вы можете сделать как

"Lorem Lorem Lorem rock-and-roll".scan(/[\w-]+/).size
=> 4
17 голосов
/ 21 января 2010

Также:

"Lorem Lorem Lorem".split.size
=> 3
4 голосов
/ 09 января 2014

Если вы заинтересованы в производительности, я написал быстрый тест:

require 'benchmark'
require 'bigdecimal/math'
require 'active_support/core_ext/string/filters'

# Where "shakespeare" is the full text of The Complete Works of William Shakespeare...

puts 'Benchmarking shakespeare.scan(/\w+/).size x50'
puts Benchmark.measure { 50.times { shakespeare.scan(/\w+/).size } }
puts 'Benchmarking shakespeare.squish.scan(/\w+/).size x50'
puts Benchmark.measure { 50.times { shakespeare.squish.scan(/\w+/).size } }
puts 'Benchmarking shakespeare.split.size x50'
puts Benchmark.measure { 50.times { shakespeare.split.size } }
puts 'Benchmarking shakespeare.squish.split.size x50'
puts Benchmark.measure { 50.times { shakespeare.squish.split.size } }

Результаты:

Benchmarking shakespeare.scan(/\w+/).size x50
 13.980000   0.240000  14.220000 ( 14.234612)
Benchmarking shakespeare.squish.scan(/\w+/).size x50
 40.850000   0.270000  41.120000 ( 41.109643)
Benchmarking shakespeare.split.size x50
  5.820000   0.210000   6.030000 (  6.028998)
Benchmarking shakespeare.squish.split.size x50
 31.000000   0.260000  31.260000 ( 31.268706)

Другими словами, squish медленно с Very Large Strings ™. Кроме этого, split быстрее (вдвое быстрее, если вы не используете squish).

2 голосов
/ 01 мая 2014

Ответы здесь имеют несколько вопросов:

  1. Они не учитывают символы utf и unicode (диакритические знаки): и т. Д. ...
  2. Они не учитывают апострофы и дефисы. Таким образом, Joe's будет считаться двумя словами Joe и 's, что, очевидно, неверно. Как и twenty-two, что является одним составным словом.

Нечто подобное работает лучше и объясняет эти проблемы:

foo.scan(/[\p{Alpha}\-']+/)

Возможно, вы захотите взглянуть на мой Количество слов драгоценный камень. Это позволяет считать слова, их вхождения, длины и пару других вещей. Это также очень хорошо задокументировано.

counter = WordsCounted::Counter.new(post.body)
counter.word_count #=> 3
counter.most_occuring_words #=> [["lorem", 3]]
# This also takes into capitalisation into account.
# So `Hello` and `hello` are counted as the same word.
2 голосов
/ 21 января 2010
"Lorem Lorem Lorem".scan(/\S+/).size
=> 3
1 голос
/ 01 июля 2014
"caçapão adipisicing elit".scan(/[\w-]+/).size 
=> 5

Но, как мы видим, в предложении всего 3 слова. Проблема связана с акцентированными символами, поскольку регулярное выражение \ w не считает их символом слова [A-Za-z0-9 _].

Улучшенное решение будет

I18n.transliterate("caçapão adipisicing elit").scan(/[\w-]+/).size
=> 3
...