How to Count Words, Characters, and Lines in a Text (Online and Code)
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 wordswell-known→ 1 word (hyphenated)C++→ 1 wordhttps://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.lengthin JavaScript. - Command line:
wc -w file.txton Linux/macOS. - Reading time: words ÷ 200 (rounded up).
- For SEO metadata, count characters not words — Google truncates by pixel width, not word count.