Text Utilities

Text Statistics

Count characters, words, lines and more from text.

Input Text
Statistics
Basic Stats
Characters
0
Chars (no spaces)
0
Words
0
Lines
0
Paragraphs
0
Sentences
0
Character Types
Uppercase
0
Lowercase
0
Digits
0
Spaces
0
Tab
0
Newlines
0
Punctuation
0
Special
0
Other Info
Longest line
0
Avg line length
0
Avg word length
0

What is Text Statistics?

Text statistics tool analyzes text and provides counts and metrics about its content.

Statistics Provided

  • Character count (with/without spaces)
  • Word count
  • Line count
  • Paragraph count
  • Reading time estimate

Use Cases

  • Content length verification
  • SEO optimization
  • Writing analysis

A counter that reports UTF-16 code units, whitespace-split word tokens, lines, blank-line-separated paragraphs and sentence-terminator runs, plus per-class counts for ASCII letters, digits, whitespace, punctuation and symbols. Use it to check a draft against a platform's character cap, compare the length of two translations, or profile how wide the lines of a code snippet run.

Every length is a UTF-16 code-unit count

All lengths on this panel come from the JavaScript string, whose length counts UTF-16 code units. The waving-hand emoji U+1F44B is stored as a surrogate pair, so it adds 2 while remaining one character; an accent typed as e plus U+0301 also adds 2. The two-line sample below holds 30 code points but is reported as 31. The no-space figure is not an independent measurement: it reruns replace(/\s/g, '') on the same string, so it always equals the character total minus the whitespace counter. Average line length divides that code-unit total by the line count and rounds, so one emoji can push a line's average past a whole number. A platform that advertises "280 characters" counts code points, which is why emoji-heavy text can pass here and still be rejected there.

Words are whitespace tokens, never segments

The word counter trims the input, then splits on /\s+/ — the same rule as wc -w, and the opposite of the segmentation that word processors apply to Chinese and Japanese. A run of CJK characters contains no whitespace, so a whole clause becomes one token; a dash standing alone between spaces is also a token; URLs, e-mail addresses and hyphenated compounds such as state-of-the-art stay whole. Punctuation glued to a word is never stripped, so Hello, counts as one word exactly like Hello. Because average word length divides the no-space code-unit count by that token count, a Chinese paragraph reports an inflated average of five or more, while a block of source code settles around three to four.

The class counters overlap and stop at ASCII

The eight character-class figures are separate match() passes over the raw string, so they are not a partition of it. Whitespace means \s: spaces, tabs, newlines, the no-break space U+00A0 and the ideographic space U+3000 all land in that single counter, which is why tabs and newlines are effectively counted twice. Letters and digits are restricted to [A-Z], [a-z] and [0-9], so É and the full-width 3 register as neither. Punctuation is a fixed literal set — ASCII . , ! ? ; : - ( ) [ ] { } " ' plus the en dash and em dash — which excludes every Chinese mark such as the full-width comma or period. The symbol set repeats !, ? and the backtick, so punctuation plus symbols can exceed the character total. Sentence count is a count of [.!?] runs, which makes it 0 for Chinese prose.

Worked example

Two lines containing an emoji and a tab

Input
Hello, 世界! 👋
Second	line — 123
Output
characters 31 | no-space 25 | words 7 | lines 2 | paragraphs 1 | sentences 1 | upper 2 | lower 13 | digits 3 | spaces 6 | tabs 1 | newlines 1 | punctuation 3 | special 1 | longest line 17 | avg line 16 | avg word 4

The 30 visible characters are 31 UTF-16 code units because the emoji is a surrogate pair, and 39 bytes in UTF-8. The seven word tokens include the standalone em dash, and the six whitespace matches are four spaces plus the tab and the newline. The exclamation mark is counted once as punctuation and once as a symbol, and 25 no-space characters divided by 7 words rounds to an average of 4.

Limits and pitfalls

  • Nothing caps the input: the textarea sets no maxlength and every counter reruns on each keystroke, so pasting a few megabytes makes typing lag, and a reload clears the text because nothing is stored.
  • Code units are not bytes: the emoji here is 2 characters but 4 bytes in UTF-8, so a byte budget (SMS 70/160, a VARCHAR or column-size limit) needs a byte counter rather than this panel.
  • Words does not segment Chinese: 你好世界 is a single token, so Chinese word counts are only meaningful alongside the character count.
  • Sentences recognises only runs of . ! ?, so text ending in a full-width period or with no final mark reports 0, and Hi!!! reports 1.
  • A trailing newline adds a line, and CRLF input keeps U+000D inside each line, so the longest-line figure runs one too high per line.

Related tools

When it goes wrong

"Paragraphs stays at 1 even though I pressed Enter between every block."

CauseThe splitter is split(/\n\s*\n/), so only an empty line ends a paragraph — a line holding nothing but spaces or tabs counts too, because \s* matches those. Single newlines, the kind Markdown leaves when it hard-wraps one paragraph, are never boundaries.

FixPut two Enters after each block. Then re-read 总字符数: every added newline is one more character, so turning 45 single newlines into blank-line pairs moves a 3,812 figure to 3,857.

"Text copied from a web page shows dozens more characters than I can see, and deleting spaces does not lower the number."

CauseBoth totals come straight from the string, so invisible characters are included. JavaScript \s does not match the zero-width space U+200B, nor U+200C, U+200D and the word joiner U+2060, which pages insert to control where lines may break. None of those are in the letter, digit, punctuation or symbol sets either, so they raise 总字符数 and 不含空格 while leaving every other card untouched.

FixRun text.replace(/[\u200B-\u200D\u2060]/g, "") on the source before pasting, or search-replace those code points out in your editor. Deleting whitespace will not remove them.

"I typed indented code into the box and the Tab card is still 0."

CauseNothing here binds a keydown handler, and a bare <textarea> does not insert a tab: the browser gives Tab to focus movement, so the character never reaches the string. The counter is reporting the truth — there is no U+0009 in the text.

FixPaste the snippet rather than typing its indentation; pasted tabs survive and are counted. If you must type it, use spaces and read the figure as indentation, not as tab usage.

"The longest-line preview looks cut off halfway, so I assume the count missed something."

CauseThe preview is a 100px-tall box with overflow: auto and word-break: break-all, so a long line wraps inside it and the remainder waits behind a scrollbar. 最长行长度 is measured on the untouched line. On a tie the earlier line is kept, because the reducer only replaces when the candidate is strictly longer.

FixTrust 最长行长度 for the number and copy the preview contents out to read the whole line. For a minified bundle, expect that one line to be the entire blob.

"A pasted JavaScript file reports hundreds of special characters, though I typed none."

Cause特殊字符 is one fixed class — ! @ # $ % ^ & * + = | \ / < > ? ~ plus the backtick. In HTML and JavaScript most of those are ordinary syntax: angle brackets for tags, slashes in paths and division, = for assignment, ! and ? for operators and ternaries. Underscore sits in neither the punctuation set nor the special set, so snake_case names score zero in both cards.

FixRead the figure as "how many syntax glyphs", not as hidden-character detection. To hunt real anomalies, filter by code point outside the ranges you expect instead of watching this card.

One concrete scenario

Fitting a 46-bullet changelog into a 4,000-character field

The release notes are 46 bullets, each ending in a period, and the form body stops at 4,000 characters. Pasted in, the panel reads 3,812 — 45 of those characters are the newlines between bullets — so 188 are left. Two figures that look wrong are correct. Sentences reads 92 because 23 bullets carry a version string such as v2.1.0, and each of its two dots starts its own run of [.!?]. Paragraphs reads 1 because bullets are separated by single newlines and the splitter only breaks on a blank line. If the renderer needs real paragraphs, insert a blank line between bullets: that costs 45 more characters and leaves 143 — one 83-character bullet rather than two. If the single-newline list renders fine, spend the 188 on two more bullets.

Frequently Asked Questions

How are words and characters counted?
English counts space-separated words; Chinese counts characters. Platforms differ: English submissions often cap words, Chinese platforms cap characters. The tool reports words, characters with and without spaces, paragraphs, sentences, and lines to cover every requirement.
How is reading time estimated?
By average reading speed: roughly 200–250 English words or 300–500 Chinese characters per minute, using a conservative value rounded to whole minutes — the same approach blog and docs platforms use, meant as guidance for readers.
Which stats matter for SEO writing?
Four: paragraph count and average length (readability — 3–4 lines per paragraph on mobile), share of long sentences (25+ words), keyword density (natural occurrence, never stuffing), and total length (ideal depth varies by intent, but substantial content generally runs 1000+ words).

Content reviewed: