17 votes

Le nombre de mots dans Rails ?

Disons que j'ai un modèle de blog avec Title et Body. Comment puis-je afficher le nombre de mots dans le corps et de caractères dans le titre ? Je veux que la sortie soit quelque chose comme ceci

Titre : Lorem Corps : Lorem Lorem Lorem

Ce billet a un nombre de mots de 3.

37voto

YOU Points 44812
"Lorem Lorem Lorem".scan(/\w+/).size
=> 3

UPDATE : si vous devez faire correspondre rock-and-roll à un seul mot, vous pouvez faire comme suit

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

20voto

P4010 Points 131

Aussi :

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

5voto

schreifels Points 301

Si vous êtes intéressé par les performances, j'ai écrit un rapide benchmark :

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

Les résultats :

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 d'autres termes, squish est lent avec Very Large Strings™. A part ça, split est plus rapide (deux fois plus rapide si vous n'utilisez pas l'option squish ).

3voto

Mohamad Points 8497

Les réponses à cette question posent quelques problèmes :

  1. Ils ne tiennent pas compte des caractères utf et unicode (diacritiques) : áâãêü etc...
  2. Ils ne tiennent pas compte des apostrophes et des traits d'union. Ainsi, Joe's sera considéré comme deux mots Joe y 's ce qui est évidemment incorrect. Comme le fera twenty-two qui est un mot composé unique.

Quelque chose comme ceci fonctionne mieux et tient compte de ces problèmes :

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

Vous pourriez vouloir regarder mon Mots comptés gemme. Il permet de compter les mots, leurs occurrences, leurs longueurs, et quelques autres choses. Il est également très bien documenté.

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.

2voto

IDBD Points 244
"Lorem Lorem Lorem".scan(/\S+/).size
=> 3

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X