tutorial rubyonrails rails guide guias generate example basics ruby word-count

rubyonrails - ¿Cuenta de palabras en Rails?



ruby server (6)

Digamos que tengo un modelo de blog con Título y Cuerpo. ¿Cómo muestro el número de palabras en Cuerpo y caracteres en Título? Quiero que la salida sea algo como esto.

Título: Lorem Cuerpo: Lorem Lorem Lorem

Este post tiene 3 palabras.


Las respuestas aquí tienen un par de cuestiones:

  1. No tienen en cuenta los caracteres utf y Unicode (diacríticos): áâãêü, etc ...
  2. No tienen en cuenta los apóstrofes y los guiones. Así que Joe''s será considerado como dos palabras de Joe y lo que obviamente es incorrecto. Al igual que twenty-two , que es una sola palabra compuesta.

Algo como esto funciona mejor y explica esos problemas:

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

Es posible que desee ver mi gema palabras contadas . Permite contar palabras, sus ocurrencias, longitudes y un par de otras cosas. También está muy bien documentado.

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.


Si estás interesado en el rendimiento, escribí un punto de referencia rápido:

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 } }

Los resultados:

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)

En otras palabras, el squish es lento con cadenas muy grandes ™. Aparte de eso, la split es más rápida (dos veces más rápida si no usas squish ).


También:

"Lorem Lorem Lorem".split.size => 3


"Lorem Lorem Lorem".scan(//S+/).size => 3


"Lorem Lorem Lorem".scan(//w+/).size => 3

ACTUALIZACIÓN : si necesita hacer coincidir rock-and-roll como una sola palabra, podría hacer lo siguiente

"Lorem Lorem Lorem rock-and-roll".scan(/[/w-]+/).size => 4


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

Pero como podemos ver, la oración tiene solo 3 palabras. El problema está relacionado con los caracteres acentuados, porque la expresión regular / w no los considera como un carácter de palabra [A-Za-z0-9_].

Una solución mejorada sería

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