2010-01-21 19 views
14

Giả sử tôi có một mô hình blog với Tiêu đề và Nội dung. Làm cách nào để hiển thị số lượng từ trong phần Nội dung và ký tự trong Tiêu đề? Tôi muốn đầu ra được cái gì đó nhưSố từ trong Rails?

Tiêu đề này: Lorem Body: Lorem Lorem Lorem

bài này có số lượng từ của 3.

Trả lời

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

CẬP NHẬT: nếu bạn cần phải phù hợp rock-and-roll như một từ, bạn có thể làm như

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

Đó chính xác là những gì tôi đang tìm kiếm. Cảm ơn. –

+2

Điều gì về "thêm một số rock-n-roll"? Có ba từ ở đây trong khi biến thể của bạn sẽ tìm thấy năm. – IDBD

+0

cũng thêm dấu nối. – YOU

16

Ngoài ra:

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

Tôi đã trải nghiệm phương pháp này đáng tin cậy hơn rất nhiều,/[\ w -] +/regex dường như không đáng tin cậy lắm. –

+2

Tôi thích điều này hơn rất nhiều. Đơn giản. Tôi đã thêm 'squish' trước' split'. – duma

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

Nếu bạn quan tâm trong việc thực hiện, tôi đã viết một chuẩn mực nhanh chóng:

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

Kết quả:

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) 

Nói cách khác, squish chậm với Very Large Strings ™. Ngoài ra, split nhanh hơn (nhanh gấp đôi nếu bạn không sử dụng squish).

2

Những câu trả lời ở đây có một vài vấn đề:

  1. Họ không chiếm utf và unicode chars (dấu): áâãêü vv ...
  2. Họ không chiếm dấu nháy và dấu gạch nối . Vì vậy, Joe's sẽ được coi là hai từ Joe's rõ ràng là không chính xác. Như sẽ twenty-two, là một từ ghép duy nhất.

Something như thế này hoạt động tốt hơn và tài khoản đối với những vấn đề:

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

Bạn có thể muốn nhìn vào Words Counted đá quý của tôi. Nó cho phép đếm các từ, sự xuất hiện của chúng, độ dài và một vài thứ khác. Nó cũng được viết rất tốt.

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. 
1
"caçapão adipisicing elit".scan(/[\w-]+/).size 
=> 5 

Nhưng như chúng ta có thể thấy, câu chỉ có 3 từ. Vấn đề có liên quan với các ký tự có dấu, bởi vì regex \ w không coi chúng là một ký tự từ [A-Za-z0-9_].

Một giải pháp cải thiện sẽ là

I18n.transliterate("caçapão adipisicing elit").scan(/[\w-]+/).size 
=> 3 
Các vấn đề liên quan