Skip to main content

How to Count the Number of Words in a String in JavaScript

Counting the words in a string is a common task in text analysis, from building simple UI counters for a textarea to performing more complex data processing. The most effective way to do this is by splitting the string into an array of words and then getting the length of that array.

This guide will teach you the modern and most robust method for counting words using a regular expression. We will also cover the simpler, more naive approach and explain why it can be unreliable.

The Core Problem: What Defines a "Word"?

The main challenge in counting words is handling whitespace correctly. A "word" is typically a sequence of non-space characters. However, a string can have multiple spaces between words, as well as leading or trailing spaces, all of which can lead to an incorrect count if not handled properly.

// Problem: All of these strings should have a word count of 3.
const str1 = 'one two three';
const str2 = ' one two three '; // Extra spaces
const str3 = 'one\ttwo\nthree'; // Other whitespace
note

A simple split(' ') will fail on the second and third strings.

The most robust and reliable way to count words is to first trim any leading/trailing whitespace and then split the string by any sequence of one or more whitespace characters.

This clean, one-line solution is the best practice.

function countWords(str) {
// Trim whitespace from the start and end of the string.
const trimmedStr = str.trim();

// Return 0 if the string is empty
if (trimmedStr === '') {
return 0;
}

// Split the string by any sequence of one or more whitespace characters.
const words = trimmedStr.split(/\s+/);

return words.length;
}

// Example Usage:
console.log(countWords('one two three')); // Output: 3
console.log(countWords(' one two three ')); // Output: 3
console.log(countWords('')); // Output: 0
console.log(countWords(' ')); // Output: 0

How the Regex Method Works

  • str.trim(): This method removes any whitespace from the beginning and end of the string. This prevents the creation of empty strings in our array from leading or trailing spaces.
  • split(/\s+/): This is the key to the solution.
    • split(): The method that splits a string into an array of substrings.
    • /\s+/: This is a regular expression.
      • \s: Matches any whitespace character (including space, tab, newline, etc.).
      • +: Is a quantifier that means "one or more."
    • Together, /\s+/ tells the split method to treat any sequence of one or more whitespace characters as a single delimiter.

The Naive Method (and its Flaws)

A simpler but less reliable method is to just split the string by a single space and then filter out the empty strings that result.

The flawed solution:

function countWordsNaive(str) {
const words = str.split(' ');
// This extra step is needed to clean up the array.
return words.filter(word => word !== '').length;
}

console.log(countWordsNaive('one two')); // Output: 2
console.log('one two'.split(' ')); // Output: ['one', '', 'two']
note

While this works, it is less efficient and less elegant than the trim() and regex approach. It also doesn't handle other whitespace characters like tabs (\t) or newlines (\n).

Practical Example: A Live Word Counter for a textarea

This is a classic use case. We want to show the user a live word count as they type into a textarea.

HTML:

<textarea id="my-textarea" placeholder="Start typing..."></textarea>
<p>Word Count: <span id="word-count">0</span></p>

JavaScript:

const textarea = document.getElementById('my-textarea');
const wordCountSpan = document.getElementById('word-count');

// Listen for the 'input' event to get real-time updates
textarea.addEventListener('input', () => {
const text = textarea.value;
const count = countWords(text);
wordCountSpan.textContent = count;
});

// Helper function from above
function countWords(str) {
const trimmedStr = str.trim();
if (trimmedStr === '') {
return 0;
}
return trimmedStr.split(/\s+/).length;
}

Conclusion

For accurately counting the words in a string, a simple split(' ') is often not enough.

  • The recommended best practice is to first use .trim() to remove leading and trailing whitespace, and then use .split(/\s+/) to split by any sequence of whitespace characters.
  • This method is robust, efficient, and handles edge cases like multiple spaces or empty strings correctly.
  • Always check for an empty string after trimming to correctly return a count of 0.