ZZerowidth CleanerInspect characters

CLAUDE WATERMARK REMOVER · METHOD TEST

Do trim() and normalize() remove hidden characters?

No: neither is a general hidden-character remover. In our 12 synthetic tests, trim(), a whitespace regex, NFC and NFKC all leave U+200B zero-width spaces, U+2060 word joiners and U+00AD soft hyphens intact. A targeted cleaner removes only its named characters. None of these tests verifies removal of Claude’s text watermark.

Tested October 3, 2026 · v24.19.0 · Unicode 17.0

Open the Claude text cleaner Download measured results

For A U+200B B, trim and normalization keep the hidden character, while targeted cleanup returns A B without a space.

One question, five methods

If you searched for a claude watermark remover because copied text fails an exact match, a shorter JavaScript command may seem enough. This experiment answers one narrower question: does each command remove the specific character in a known input? It does not investigate where a character came from.

We constructed 12 strings from explicit Unicode escapes. They are test fixtures, not samples collected from Claude. Each string passes independently through s.trim(), s.replace(/\s/g, ''), s.normalize('NFC'), s.normalize('NFKC') and the current homepage cleaner. The cleaner runs with “Remove invisible” enabled and dash mode set to “Keep”.

For the cleaner column, we executed the actual app.js with a minimal DOM harness, rather than substituting a broader regular expression. Its removal set is U+200B, U+00AD, U+2060, U+FEFF and U+034F. Our JSON record includes the script’s SHA-256 hash, runtime and complete outputs. Every table cell shows the full output as code points, including characters that look invisible.

Measured outputs for all 12 fixtures

Exact output code points. U+0041 is A; U+0042 is B. No spaces are inserted by the cleaner.
Fixture / inputtrim()/\s/g → emptyNFCNFKCOur cleaner
Internal zero-width space
U+0041 U+200B U+0042
U+0041 U+200B U+0042U+0041 U+200B U+0042U+0041 U+200B U+0042U+0041 U+200B U+0042U+0041 U+0042
Edge zero-width spaces
U+200B U+0041 U+200B
U+200B U+0041 U+200BU+200B U+0041 U+200BU+200B U+0041 U+200BU+200B U+0041 U+200BU+0041
Internal word joiner
U+0041 U+2060 U+0042
U+0041 U+2060 U+0042U+0041 U+2060 U+0042U+0041 U+2060 U+0042U+0041 U+2060 U+0042U+0041 U+0042
Internal soft hyphen
U+0041 U+00AD U+0042
U+0041 U+00AD U+0042U+0041 U+00AD U+0042U+0041 U+00AD U+0042U+0041 U+00AD U+0042U+0041 U+0042
Internal BOM
U+0041 U+FEFF U+0042
U+0041 U+FEFF U+0042U+0041 U+0042U+0041 U+FEFF U+0042U+0041 U+FEFF U+0042U+0041 U+0042
Leading BOM
U+FEFF U+0041
U+0041U+0041U+FEFF U+0041U+FEFF U+0041U+0041
Combining grapheme joiner
U+0041 U+034F U+0042
U+0041 U+034F U+0042U+0041 U+034F U+0042U+0041 U+034F U+0042U+0041 U+034F U+0042U+0041 U+0042
Non-breaking space
U+0041 U+00A0 U+0042
U+0041 U+00A0 U+0042U+0041 U+0042U+0041 U+00A0 U+0042U+0041 U+0020 U+0042U+0041 U+00A0 U+0042
Paragraph break
U+0041 U+000A U+0042
U+0041 U+000A U+0042U+0041 U+0042U+0041 U+000A U+0042U+0041 U+000A U+0042U+0041 U+000A U+0042
Decomposed accent
U+0065 U+0301
U+0065 U+0301U+0065 U+0301U+00E9U+00E9U+0065 U+0301
Compatibility ligature
U+FB01
U+FB01U+FB01U+FB01U+0066 U+0069U+FB01
Emoji with joiner
U+1F469 U+200D U+1F4BB
U+1F469 U+200D U+1F4BBU+1F469 U+200D U+1F4BBU+1F469 U+200D U+1F4BBU+1F469 U+200D U+1F4BBU+1F469 U+200D U+1F4BB

What the results mean for a broken paste

Zero-width space is not JavaScript whitespace. The internal and edge U+200B fixtures survive both trimming and the whitespace regex. They also survive both normalization forms. The homepage cleaner deletes U+200B, so A + U+200B + B becomes AB. If that hidden break separated two words, deletion can join those words; review the output before using it.

Location changes the BOM result. A leading U+FEFF disappears with trim(), but an internal one remains. The whitespace regex deletes it in either position. NFC and NFKC keep it. Our cleaner deletes it in both fixtures. This tests a character already inside a JavaScript string; it does not test file decoders or whether a file’s encoding marker should be retained.

Whitespace removal can damage structure. The regex deletes the U+00A0 between A and B and the U+000A paragraph break. Both outputs become AB. The homepage cleaner preserves both characters. NFKC converts the non-breaking space to U+0020 ordinary space, while NFC leaves it unchanged. Choose space conversion or paragraph editing deliberately rather than assuming it is invisible-character cleanup.

Normalization handles equivalence. NFC composes e + U+0301 into U+00E9. NFKC does that too and additionally changes the U+FB01 ligature into the letters f and i. The cleaner keeps these inputs unchanged. Normalization is useful for a different class of exact-match problem, but is not a replacement for selective removal.

The emoji fixture is preserved byte-for-byte as a string by every method here. Its U+200D joiner is outside our homepage removal set. This is evidence for this one sequence, not a test of every emoji or script. Joiners may be meaningful; a broader cleaner needs its own preservation tests.

Reproduce the measurements

Download the standalone Node.js harness and run node reproduce.cjs. It downloads the public homepage script, prints its hash and emits all 60 method outputs as JSON. Compare its hash with the saved record: later changes to the cleaner or runtime may change a rerun. For an offline repeat of this snapshot, download the tested script into the same directory and run node reproduce.cjs tested-app.js.

const sample = "A\u200BB";
console.log([...sample.trim()].map(c => c.codePointAt(0)));
// [65, 8203, 66]: the zero-width space is still there
console.log(sample.replace(/\u200B/g, ""));
// AB: targeted deletion; no inserted word separator

Choose the operation that matches the failure

For unwanted whitespace at the ends, trim() is suitable. For canonically equivalent spellings, consider NFC. For a named accidental hidden character, inspect the code points and remove only the characters you intend to change. The position-by-position inspector helps locate them. Keep an original copy and compare words, line breaks and meaningful joiners afterwards.

A clean character result does not identify an author, certify that a passage has no watermark or predict an AI detector score. These fixtures contain no known Anthropic watermark signal. See the separate Unicode and watermark explanation for that distinction.

Primary references

The ECMAScript trim specification defines trimming at the ends using WhiteSpace and LineTerminator. Its normalize specification defines the supported normalization forms. Unicode Annex #15 explains canonical and compatibility normalization. These references describe the operations; the table above is our own measured dataset.