CLAUDE WATERMARK REMOVER · PRACTICAL TEST
Why does an empty regex replacement split a cleaned emoji?
Our global empty pattern inserts a separator between the emoji’s UTF-16 surrogates without u. With gu, it keeps the code point together. Both versions still insert at the ends, including one separator for an empty string.
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. 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.
| Fixture and mode | Input string and code points | Output and cleaner status | Observed before / after |
|---|---|---|---|
| Marker before emoji direct string / keep / invisible true | "😀"U+200B U+1F600 | "😀"Removed 1 invisible character | {"units":3,"points":2,"unitReplacement":"||\ud83d|\ude00|","unicodeReplacement":"||😀|"}{"units":2,"points":1,"unitReplacement":"|\ud83d|\ude00|","unicodeReplacement":"|😀|"} |
| Emoji control direct string / keep / invisible true | "😀"U+1F600 | "😀"No selected invisible characters found | {"units":2,"points":1,"unitReplacement":"|\ud83d|\ude00|","unicodeReplacement":"|😀|"}{"units":2,"points":1,"unitReplacement":"|\ud83d|\ude00|","unicodeReplacement":"|😀|"} |
| ASCII control direct string / keep / invisible true | "AB"U+0041 U+0042 | "AB"No selected invisible characters found | {"units":2,"points":2,"unitReplacement":"|A|B|","unicodeReplacement":"|A|B|"}{"units":2,"points":2,"unitReplacement":"|A|B|","unicodeReplacement":"|A|B|"} |
| Empty control direct string / keep / invisible true | "" | ""No selected invisible characters found | {"units":0,"points":0,"unitReplacement":"|","unicodeReplacement":"|"}{"units":0,"points":0,"unitReplacement":"|","unicodeReplacement":"|"} |
Zero-width matches still move through the input
The observer replaces every match of an empty noncapturing pattern with a pipe. After the marker is removed from the leading-emoji fixture, the ordinary global expression inserts one pipe between the emoji’s two UTF-16 surrogates as well as pipes at either end. Unicode global mode instead keeps the emoji together between two pipes. The plain emoji control produces the same distinction without cleaning. Both versions give pipes around and between A and B in the ASCII control. Both produce one pipe for the empty control. We retain JSON-escaped strings so the separated surrogate halves remain inspectable without relying on how a font renders the damaged-looking result.
An inserted boundary is not necessarily a displayed-character boundary
The pattern consumes no source characters. Its repeated advancement policy, rather than a dot width or a replacement dollar token, determines where the next empty match occurs. Our earlier dollar-template guide studies interpretation of the replacement string; this replacement is a literal pipe with no special template notation. The matchAll guide records offsets of actual matches under another pattern. Here the question is output construction at empty match positions. Unicode mode tracks code points in this fixture, not complete grapheme clusters in arbitrary text. We do not test combining sequences, flags, joiner emoji, custom Symbol.replace methods or a manually written exec loop. No system clipboard or original file is modified.
Select the boundary required by the destination transformation
When inserting separators, identify whether the intended unit is a UTF-16 unit, a code point or a displayed cluster. Enabling u resolves the surrogate split for this emoji, but does not establish a general visual segmentation solution. Our earlier grapheme-prefix experiment addresses a different boundary and can guide a separate check. The empty-string control also matters: zero source length does not imply zero replacement output for this operation. Retain the original string if a generated transformation must be reversed, and inspect exact escapes when separators appear inside a character. The attached harness records the cleaner output before either replacement, locating this later alteration precisely without suggesting that the homepage cleaner itself splits emoji.
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.