Cat Toolbox
Help CatBlog About Partnership 中文

How to Clean Up and Count Text, and Why the Two Counters Disagree

TextUpdated 2026-09-29

Most text jobs are two jobs: make the text tidy, then know what you are holding. Text Formatter and Text Statistics do exactly that, both entirely in the page — nothing is sent anywhere, and there is no length limit on the box. Both are worth reading before you trust their output, because each makes a handful of decisions for you.

Fifteen actions, and only some of them respect your line breaks

Every action reads the box and writes a result below it. Which unit it works on matters more than the label suggests:

  • Character-level — UPPERCASE, lowercase, Title Case. Line structure is untouched.
  • Line-level — Trim Lines, Remove Empty Lines, Remove Duplicates, Sort Ascending/Descending, Add Line Numbers, Remove Line Numbers, Reverse Lines. Each one splits on line breaks, works, then rejoins.
  • Whitespace-level — Merge Spaces, and the two width conversions.

One consequence is easy to miss: Add Line Numbers numbers every line, including blank ones, so a paragraph break in your source becomes a numbered empty line. Remove Empty Lines first, then number — the other order leaves gaps in your sequence.

Title Case lowercases the rest of each word, not just capitalises the first letter. McDonald comes out as Mcdonald, iPhone as Iphone. If your text already contains camelCase or surname prefixes, skip this action.

Merge Spaces is not Trim Lines

They look like two spellings of the same thing and are not:

  • Merge Spaces collapses every run of spaces and tabs into a single space anywhere in the line, and also removes leading and trailing whitespace on each line. It therefore destroys indentation — never run it on code, YAML or anything whose meaning lives in leading spaces.
  • Trim Lines only strips whitespace at the start and end of each line, leaving internal spacing and relative indentation alone.

For text pasted out of a PDF or a web page, Merge Spaces is usually what you want. For anything structured, start with Trim Lines.

Sorting uses pinyin and reads numbers as numbers

Both sort actions use one comparison rule: Chinese characters order by pinyin pronunciation, digits inside a line are compared numerically, and case is ignored.

That gives you behaviour that plain alphabetical sorting would not:

  • chapter9 sorts before chapter10, which plain alphabetical sorting gets backwards.
  • Chinese orders by reading, not by code point: 阿 (ā) comes near the front, 张 (zhāng) near the back.
  • Apple and apple count as equal, and equal lines keep the order they had in your input.

If you need byte/code-point order instead — for example to match another system's output — this is the wrong tool for that step.

Remove Duplicates is exact, and has one trap

Deduplication compares whole lines, exactly: case-sensitive and whitespace-sensitive. Foo and foo (one trailing space) are two different lines, and Foo and Foo will both survive. Run Trim Lines first if you want near-misses to collapse.

The trap is in how the comparison is stored: the tool keeps a plain object as its "already seen" set. Any line whose text equals a property name inherited from Object.prototype — toString, constructor, valueOf, hasOwnProperty, __proto__ — tests as already-seen on its first appearance and is dropped from the result. Rare, but if your file is a list of identifiers and one of those is missing, this is why.

Full-width and half-width do not cancel out

  • Full-width to Half-width converts the standard full-width ASCII block (U+FF01–U+FF5E) to normal ASCII, and turns the ideographic space U+3000 into an ordinary space. It leaves CJK-specific marks such as 、 。 《》 alone — those have no ASCII counterpart.
  • Half-width to Full-width converts every printable ASCII character, U+0020 to U+007E. That includes letters and digits, and includes the space, which becomes U+3000.

So the second action on English prose produces a wall of FULL-WIDTH text — correct behaviour, occasionally what you want for CJK typography alignment, usually not what you want by accident.

Reverse Lines and Reverse Text are different edits

Reverse Lines flips the order of lines and keeps each line intact — a quick way to get newest-first out of a log. Reverse Text flips individual characters, so every word reads backwards. It reverses by code point, which means emoji and other astral characters survive intact; a naive per-UTF-16-unit reversal would split them.

Why the two "character" numbers differ

Text Formatter's counter under the input box and Text Statistics' Characters figure are not the same measurement, and a text containing emoji or rare CJK ideographs will show it:

  • The formatter's counter counts UTF-16 code units, so 😀 is 2 and characters outside the Basic Multilingual Plane count double.
  • Text Statistics counts code points, so the same 😀 is 1.

Line counts differ too. The formatter reports 0 lines for an empty box; Text Statistics starts at 1 and adds one for every line break, including a trailing one — so a file that ends with a newline reads as one line longer than the number of visible lines. Text Statistics also treats a lone carriage return as a line break, which only shows up on old Mac-era files.

The word count is really two numbers

Text Statistics has a large headline number and a grid entry that both look like "words":

  • Total words (headline) = the count of Chinese characters plus the count of English words. A paragraph of pure Chinese gives you a healthy number here.
  • Words (in the grid) = English words only. The same Chinese paragraph shows 0.

English words are matched as runs of ASCII letters, optionally joined by an internal apostrophe or hyphen. That has three effects worth knowing:

  1. Accented words split. café matches as caf — one word — and some day is two. So café naïve reports 3 Total words on a text with two words in it, because the leftover fragments count.
  2. Digits are never words. Numbers are counted separately, and a number with separators counts once: 1,234.50 is one Number.
  3. Letters, uppercase, lowercase and digits count ASCII only. é adds a Character but no Letter.

The frequency chips follow the same split: up to eight English words (single letters excluded) followed by up to eight Chinese characters, in one unlabelled row. A chip list mixing 的 and because is two different rankings read back to back, not one.

Sentences, and the reading-time divisor

Sentence counting splits on 。 ! ? . ! ?, and consecutive marks collapse: Wait... what?! is two sentences, not four. The same rule inflates text containing decimals or abbreviations — 3.14 and Mr. each read as a sentence boundary, and Avg sent len inherits that error.

Reading time is Total words ÷ 300, rounded up to a minimum of 1 minute; speaking time uses 180. Because the numerator mixes Chinese characters with English words, the estimate is a hybrid rate rather than a true words-per-minute figure. It is a reasonable comparison between your own drafts and a poor absolute claim for a publication schedule.

The result box does not update when you type

This is the one behaviour that produces wrong answers silently. Typing refreshes only the counter under the input box; the result below stays whatever the last action produced, and the boxes look unchanged. After editing input, re-click the action — and remember Result → Input feeds the previous result back as new input, which is how you chain Merge Spaces into Remove Duplicates without a copy-paste.

Two smaller notes: the action buttons do nothing at all when the input is empty (no message), and Copy Result stays silent if the browser refuses clipboard access — the "✓ Copied" confirmation only appears on success.

Nothing is stored

Neither page writes to storage, keeps a history, or exports a file. Clear empties both boxes, and on Text Statistics both Clear and Load Example overwrite your input immediately, with no confirmation. If a result matters, copy it out before you touch anything else. Text you want to keep belongs on the browser notepad, which is the one page here that does persist.

Tools used in this guide

Advertisement