Zerowidth CleanerAll measured guides

CLAUDE WATERMARK REMOVER · PRACTICAL TEST

Why does a dot regex still fail after I clean a line break?

Cleanup retains our line feed and U+2028. The s flag lets a dot match them; the u flag is also needed for our emoji to occupy one dot. Removing U+200B can instead make a required middle character disappear.

Tested October 14, 2026 · v24.19.0 · 4 measured runs

Open the Claude text cleaner · Full measured data

Code-point comparison for Selected marker

Measured inputs and outputs

These are locally constructed test strings, not evidence that Claude inserts these characters. We executed the saved homepage script snapshot with a minimal DOM harness and compared exact strings. The invisible-checkbox state and dash mode appear in each row. The observations below test this page's specific question. Destination observations run independently on the exact input and cleaned strings in the recorded Node runtime. We make no detector-score or statistical-watermark removal claim.

Before and after observations; full code points and strings are in the JSON download.
Fixture and modeInput string and code pointsOutput and cleaner statusObserved before / after
Selected marker
direct string / keep / invisible true
"A​B"
U+0041 U+200B U+0042
"AB"
Removed 1 invisible character
{"ordinary":true,"dotAll":true,"dotAllUnicode":true,"units":3}
{"ordinary":false,"dotAll":false,"dotAllUnicode":false,"units":2}
Line feed
direct string / keep / invisible true
"A\nB"
U+0041 U+000A U+0042
"A\nB"
No selected invisible characters found
{"ordinary":false,"dotAll":true,"dotAllUnicode":true,"units":3}
{"ordinary":false,"dotAll":true,"dotAllUnicode":true,"units":3}
Line separator
direct string / keep / invisible true
"A
B"
U+0041 U+2028 U+0042
"A
B"
No selected invisible characters found
{"ordinary":false,"dotAll":true,"dotAllUnicode":true,"units":3}
{"ordinary":false,"dotAll":true,"dotAllUnicode":true,"units":3}
Emoji middle
direct string / keep / invisible true
"A😀B"
U+0041 U+1F600 U+0042
"A😀B"
No selected invisible characters found
{"ordinary":false,"dotAll":false,"dotAllUnicode":true,"units":4}
{"ordinary":false,"dotAll":false,"dotAllUnicode":true,"units":4}

A successful match can become a failure after deletion

We anchor the same A-dot-B pattern around four invented inputs. The selected-marker fixture has exactly one middle UTF-16 unit and matches all three expressions before cleanup. Once U+200B is removed, the output is AB and every expression fails because the pattern still demands a middle character. The line-feed control fails the ordinary expression but succeeds with dotAll, and the line-separator control behaves the same way. Both controls survive the actual cleaner unchanged. The emoji control occupies two units and fails the ordinary and dotAll-only expressions. Adding Unicode mode alongside dotAll lets that complete code point satisfy the single dot. This is why fewer hidden characters cannot predict whether an expression should return true.

Flags define separate contracts for the same visible pattern

The observer uses three fresh expressions and records their booleans and the input unit count. It performs no repeated global search and has no lastIndex cursor, keeping this question separate from our stateful and sticky-regex guides. DotAll changes the treatment of line terminators; Unicode mode changes the unit consumed for the supplementary character in this test. Neither setting repairs the required width after a selected deletion. We do not test full Unicode grapheme clusters, every regex flag combination, performance on large documents or the parser inside a particular editor. A family emoji can contain several code points, so the success of this single supplementary character is not a promise that every visual character fits one dot.

Inspect the pattern and its flags before changing line structure

If a pasted paragraph fails a match, preserve its exact line breaks and record the expression and flags that the destination actually uses. Decide whether crossing a line is intended before enabling dotAll. Do not delete paragraph boundaries simply to force a match: they can carry useful structure that the cleaner retains. The four downloadable rows show a removed marker, two preserved terminators and an emoji width control with independently executed observations. They do not implement a paragraph validator or determine which expression is correct for your application. After deliberate cleanup, rerun the same destination pattern on the edited version; a match changing from true to false may reflect a required character being removed rather than a new encoding problem.

Reproduce this test

Save reproduce.cjs and tested-app.js in the same folder. Run the command below with Node.js. The harness prints its runtime, script SHA-256 and every measured row. Compare those rows with the original record. Using a newer script or runtime creates a new experiment; retain the version information with your rerun.

node reproduce.cjs

Reference and next check

ECMAScript string operations provides the relevant primary definition. The table and fixture analysis are original measurements. For broader inspection, use our Unicode inspector. Read the scope distinction before interpreting cleanup as a watermark result.