# Counting words

**URL:** <https://www.ruby-forum.com/t/counting-words/94323>\
**Category:** Ruby\
**Created:** [April 28, 2006, 7:47pm UTC](https://www.ruby-forum.com/t/counting-words/94323 "2006-04-28T19:47:06Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![jamal86](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ebca7d/32.png) [@jamal86](https://www.ruby-forum.com/u/jamal86)\
**Post date:** [April 28, 2006, 7:47pm UTC](https://www.ruby-forum.com/t/counting-words/94323/1 "2006-04-28T19:47:06Z")

</div>

I’ve research this but am still having trouble getting it right …  
Can someone give me code that counts the number of words in a string via  
RegExp and MatchData objects? I think I’d like a word to be defined as  
contiguous characters surrounded by white space (or the start/end of the  
string), though am open to other interpretations.

Jamal

---

<div class="post-metadata">

**Author:** ![jamal86](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ebca7d/32.png) [@jamal86](https://www.ruby-forum.com/u/jamal86)\
**Post date:** [April 28, 2006, 7:50pm UTC](https://www.ruby-forum.com/t/counting-words/94323/2 "2006-04-28T19:50:13Z")

</div>

On Sat, Apr 29, 2006 at 02:43:30AM +0900, Jamal M. wrote:

> I’ve research this but am still having trouble getting it right …  
> Can someone give me code that counts the number of words in a string via  
> RegExp and MatchData objects? I think I’d like a word to be defined as  
> contiguous characters surrounded by white space (or the start/end of the  
> string), though am open to other interpretations.

Here is a naive implementation:

class String  
def words  
scan(/\b\S+\b/)  
end  
end

‘this is a sentence with some words’.words  
=\> [“this”, “is”, “a”, “sentence”, “with”, “some”, “words”]  
‘this is a sentence with some words’.words.size  
=\> 7

marcel

---

<div class="post-metadata">

**Author:** ![jamal86](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ebca7d/32.png) [@jamal86](https://www.ruby-forum.com/u/jamal86)\
**Post date:** [April 28, 2006, 7:50pm UTC](https://www.ruby-forum.com/t/counting-words/94323/3 "2006-04-28T19:50:18Z")

</div>

On 4/28/06, Jamal M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I’ve research this but am still having trouble getting it right …  
> Can someone give me code that counts the number of words in a string via  
> RegExp and MatchData objects? I think I’d like a word to be defined as  
> contiguous characters surrounded by white space (or the start/end of the  
> string), though am open to other interpretations.
> 
> Jamal

I’m a bit of a nuby, and this is my first post to the list, but I  
think the following one-liner will do the job:

number\_of\_words = string.split(/\s/).length

I haven’t tested it because I’m at work without access to a Ruby  
interpreter :(.

---

<div class="post-metadata">

**Author:** ![jamal86](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ebca7d/32.png) [@jamal86](https://www.ruby-forum.com/u/jamal86)\
**Post date:** [April 28, 2006, 7:53pm UTC](https://www.ruby-forum.com/t/counting-words/94323/4 "2006-04-28T19:53:33Z")

</div>

On 4/28/06, Bira [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> number\_of\_words = string.split(/\s/).length

Eh, sorry. I meant to write:

number\_of\_words = string.split(/\s+/).length

The “+” is needed to cover words with more than one whitespace  
character between them.

---

<div class="post-metadata">

**Author:** ![jamal86](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ebca7d/32.png) [@jamal86](https://www.ruby-forum.com/u/jamal86)\
**Post date:** [April 28, 2006, 8:46pm UTC](https://www.ruby-forum.com/t/counting-words/94323/5 "2006-04-28T20:46:13Z")

</div>

2006/4/28, Jamal M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> I’ve research this but am still having trouble getting it right …  
> Can someone give me code that counts the number of words in a string via  
> RegExp and MatchData objects? I think I’d like a word to be defined as  
> contiguous characters surrounded by white space (or the start/end of the  
> string), though am open to other interpretations.

s.scan(/\w+/).size

---

<div class="post-metadata">

**Author:** ![jamal86](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ebca7d/32.png) [@jamal86](https://www.ruby-forum.com/u/jamal86)\
**Post date:** [April 28, 2006, 11:04pm UTC](https://www.ruby-forum.com/t/counting-words/94323/6 "2006-04-28T23:04:43Z")

</div>

One way is like this:

irb(main):020:0\> a=“This is a test.”  
=\> “This is a test.”  
irb(main):021:0\> a.scan(/\b\S.\*?\b/).size  
=\> 4  
irb(main):022:0\>

The Regexp in line 21 rewritten in a more readable form is:

a.scan(/  
\b (?# a word boundary )  
\S (?# a character that is not a space )  
._? (?# maybe (_) some more characters (.), but don’t be greedy  
(?))  
\b (?# a word boundary )  
/x

btw, the Regexp above actually works because of the x at the end,  
meaning an extended regexp.

Regards,  
JJ

On Friday, April 28, 2006, at 04:35PM, Jamal M.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I’ve research this but am still having trouble getting it right …  
> Can someone give me code that counts the number of words in a string via  
> RegExp and MatchData objects? I think I’d like a word to be defined as  
> contiguous characters surrounded by white space (or the start/end of the  
> string), though am open to other interpretations.
> 
> Jamal

* * *

Help everyone. If you can’t do that, then at least be nice.

---

<div class="post-metadata">

**Author:** ![jamal86](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ebca7d/32.png) [@jamal86](https://www.ruby-forum.com/u/jamal86)\
**Post date:** [May 3, 2006, 7:08pm UTC](https://www.ruby-forum.com/t/counting-words/94323/7 "2006-05-03T19:08:31Z")

</div>

“Marcel Molina Jr.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> def words  
> scan(/\b\S+\b/)  
> end  
> end

And quite bit more efficient, memory-wise:

class String  
def count\_words  
n = 0  
scan(/\b\S+\b/) { n += 1}  
n  
end  
end

Making String#count take regexps would be nice (same for #delete).

---

<div class="post-metadata">

**Author:** ![jamal86](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ebca7d/32.png) [@jamal86](https://www.ruby-forum.com/u/jamal86)\
**Post date:** [April 28, 2006, 11:10pm UTC](https://www.ruby-forum.com/t/counting-words/94323/8 "2006-04-28T23:10:57Z")

</div>

Bira wrote:

> –  
> Bira  
> [http://compexplicita.blogspot.com](http://compexplicita.blogspot.com)  
> [http://sinfoniaferida.blogspot.com](http://sinfoniaferida.blogspot.com)

Just plain string.split.length will work as well, and should handle line  
breaks too:

> irb(main):001:0\> “these are some words”.split.length  
> =\> 4  
> irb(main):002:0\> “these are \n some\nwords”.split.length  
> =\> 4  
> irb(main):003:0\> “these are \n some\nwords”.split  
> =\> [“these”, “are”, “some”, “words”]  
> irb(main):004:0\>

Hope that helps.

-Justin
