All Tools / Blog / How to Count Words, Characters, and Lines in a Text (Online and Code)

How to Count Words, Characters, and Lines in a Text (Online and Code)

4 min read

Word counting sounds trivial until you run into the edge cases: does a hyphenated word count as one or two? Do URLs count? What about words in multiple languages? This guide covers accurate counting methods for each environment.

In the browser

Paste text into the word counter and get an instant count of words, characters, characters without spaces, sentences, paragraphs, and estimated reading time. Updates as you type — useful when you're writing within a limit (Twitter threads, grant applications, article submissions).

What counts as a word?

The standard definition: a sequence of non-whitespace characters separated by whitespace. Under this definition:

  • hello world → 2 words
  • well-known → 1 word (hyphenated)
  • C++ → 1 word
  • https://example.com/path?q=1 → 1 word
  • "quoted text" → 2 words (punctuation is attached to adjacent words)

For most purposes this is fine. If you need to exclude URLs, strip them before counting.

JavaScript

Basic word count:

function wordCount(text) {
    return text.trim().split(/\s+/).filter(Boolean).length;
}

console.log(wordCount("Hello world"));        // 2
console.log(wordCount("  spaces   matter  ")); // 2
console.log(wordCount(""));                    // 0

The filter(Boolean) removes empty strings that result from multiple consecutive spaces or leading/trailing whitespace.

Character counts:

function textStats(text) {
    return {
        characters: text.length,
        charactersNoSpaces: text.replace(/\s/g, '').length,
        words: text.trim() === '' ? 0 : text.trim().split(/\s+/).length,
        sentences: (text.match(/[.!?]+/g) || []).length,
        paragraphs: text.trim() === '' ? 0 : text.trim().split(/\n\s*\n/).length,
        readingTimeMinutes: Math.ceil(text.trim().split(/\s+/).length / 200),
    };
}

const stats = textStats("Hello world. This is a test.\n\nSecond paragraph.");
console.log(stats);
// {
//   characters: 48,
//   charactersNoSpaces: 40,
//   words: 9,
//   sentences: 2,
//   paragraphs: 2,
//   readingTimeMinutes: 1
// }

Reading time uses 200 words per minute (the commonly cited average for reading online text; 250 wpm for books).

Frequency map (which words appear most):

function wordFrequency(text) {
    const words = text.toLowerCase().match(/\b[a-z']+\b/g) || [];
    return words.reduce((freq, word) => {
        freq[word] = (freq[word] || 0) + 1;
        return freq;
    }, {});
}

const freq = wordFrequency("the cat sat on the mat the cat");
const sorted = Object.entries(freq).sort((a, b) => b[1] - a[1]);
console.log(sorted);
// [['the', 3], ['cat', 2], ['sat', 1], ['on', 1], ['mat', 1]]

Python

Word and character counts:

def text_stats(text: str) -> dict:
    words = text.split()
    sentences = len([s for s in text.replace('!', '.').replace('?', '.').split('.') if s.strip()])
    paragraphs = len([p for p in text.strip().split('\n\n') if p.strip()])

    return {
        'characters': len(text),
        'characters_no_spaces': len(text.replace(' ', '')),
        'words': len(words),
        'sentences': sentences,
        'paragraphs': paragraphs,
        'reading_time_minutes': max(1, len(words) // 200),
    }

sample = "Hello world. This is a test.\n\nSecond paragraph here."
print(text_stats(sample))

Count words in a file:

def count_words_in_file(filepath: str) -> dict:
    with open(filepath, encoding='utf-8') as f:
        text = f.read()
    return text_stats(text)

print(count_words_in_file('essay.txt'))

Word frequency:

from collections import Counter
import re

def word_frequency(text: str, top_n: int = 10) -> list[tuple[str, int]]:
    words = re.findall(r"\b[a-z']+\b", text.lower())
    return Counter(words).most_common(top_n)

sample = "the cat sat on the mat the cat"
print(word_frequency(sample))
# [('the', 3), ('cat', 2), ('sat', 1), ('on', 1), ('mat', 1)]

Command line

Linux/macOS:

# Count words
wc -w file.txt

# Count lines, words, characters
wc file.txt
# output: lines words chars filename

# Count words in a string
echo "hello world" | wc -w
# 2

# Count words in multiple files, with totals
wc -w *.txt

Count unique words (vocabulary size):

cat file.txt | tr '[:upper:]' '[:lower:]' | tr -cs '[:alpha:]' '\n' | sort | uniq -c | sort -rn | head -20

This pipeline: lowercase → split to one word per line → sort → count unique → sort by count.

Python one-liner:

python3 -c "import sys; text=open(sys.argv[1]).read(); print(len(text.split()))" file.txt

Windows PowerShell:

(Get-Content file.txt -Raw).Split() | Where-Object { $_ } | Measure-Object | Select-Object -ExpandProperty Count

Common character limits by platform

Platform / format Limit What counts
Twitter / X post 280 characters Characters (not words)
SMS 160 characters Characters per segment
Meta title (SEO) 50–60 characters Characters
Meta description (SEO) 150–160 characters Characters
LinkedIn post 3,000 characters Characters
Instagram caption 2,200 characters Characters
Google My Business post 1,500 characters Characters
Medium article (optimal) 1,500–2,500 words Words
Blog post (SEO average) 1,200–2,500 words Words

For SEO titles and descriptions, character count matters more than word count because Google truncates based on pixel width (roughly 580 px for titles).

Excluding specific content before counting

Count words while ignoring URLs:

function countWordsNoUrls(text) {
    const noUrls = text.replace(/https?:\/\/\S+/g, '');
    return noUrls.trim().split(/\s+/).filter(Boolean).length;
}

Count words while ignoring code blocks (Markdown):

import re

def count_words_no_code(markdown: str) -> int:
    # Remove fenced code blocks
    no_code = re.sub(r'```[\s\S]*?```', '', markdown)
    # Remove inline code
    no_code = re.sub(r'`[^`]+`', '', no_code)
    return len(no_code.split())

Key takeaways

  • Word count: text.split() in Python, text.trim().split(/\s+/).filter(Boolean) in JavaScript.
  • Character count: len(text) in Python, text.length in JavaScript.
  • Command line: wc -w file.txt on Linux/macOS.
  • Reading time: words ÷ 200 (rounded up).
  • For SEO metadata, count characters not words — Google truncates by pixel width, not word count.