CLAUDE WATERMARK REMOVER · PRACTICAL TEST
Can hidden-character cleanup change what a regex matches?
Yes. Cleaning the literal pattern ^A + U+200B + B$ makes it match AB. A written regex escape survives the text pass and still matches the hidden character when compiled.
Open the Claude text cleaner · Full measured data
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. Invisible removal is enabled; the dash mode appears in each row. The observations below test this page's specific question. We make no detector-score or statistical-watermark removal claim.
| Fixture and mode | Input string and code points | Output and cleaner status | Observed before / after |
|---|---|---|---|
| Literal pattern direct string / keep | "^AB$"U+005E U+0041 U+200B U+0042 U+0024 | "^AB$"Removed 1 invisible character | {"source":"^AB$","matchesAB":false,"matchesHidden":true}{"source":"^AB$","matchesAB":true,"matchesHidden":false} |
| Written escape direct string / keep | "^A\\u200BB$"U+005E U+0041 U+005C U+0075 U+0032 U+0030 U+0030 U+0042 U+0042 U+0024 | "^A\\u200BB$"No selected invisible characters found | {"source":"^A\\u200BB$","matchesAB":false,"matchesHidden":true}{"source":"^A\\u200BB$","matchesAB":false,"matchesHidden":true} |
| Baseline pattern direct string / keep | "^AB$"U+005E U+0041 U+0042 U+0024 | "^AB$"No selected invisible characters found | {"source":"^AB$","matchesAB":true,"matchesHidden":false}{"source":"^AB$","matchesAB":true,"matchesHidden":false} |
Measure behavior after compilation
We compile each original and cleaned pattern with RegExp and the Unicode flag. The literal pattern initially matches only the hidden-character candidate. After cleanup it matches AB and rejects the hidden candidate. The written escape pattern preserves its source spelling and matching behavior because the cleaner sees ASCII characters rather than U+200B. The baseline matches AB throughout. This is an executable semantic comparison, beyond checking whether a pattern still compiles.
A surviving escape can be intentional
Regex syntax represents characters at compilation time. A literal character and an escape can describe the same matching requirement while taking different paths through a plain-text cleaner. If a pattern exists to find accidental zero-width spaces, cleaning it can remove its purpose. We tested exactly these anchored patterns in the recorded Node runtime; we did not test another regex engine, flags, character classes, replacement functions or production search workloads. ECMAScript defines the JavaScript regex semantics used here.
Treat patterns as code with expectations
Retain the original pattern and a small positive and negative sample set. State which strings should match, then rerun those checks after any text edit. Prefer an explicit escape in documentation demonstrating invisible-character matching. Review string-literal escaping separately if a pattern is embedded in JavaScript or JSON, since that introduces another decoding stage. The homepage neither recognizes regex source nor protects it. Its successful cleanup message describes a deletion operation, not preservation of a program requirement.
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.cjsReference 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.