CLAUDE WATERMARK REMOVER · PRACTICAL TEST
Why does /k/iu match a Kelvin sign that /k/i rejects?
The u flag changes our ignore-case results: Kelvin K matches k and long s ſ matches s only with iu. Cleanup preserves those letters. Removing a preceding U+200B exposes the same anchored Kelvin match.
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 |
|---|---|---|---|
| Marked Kelvin sign direct string / keep / invisible true | "K"U+200B U+212A | "K"Removed 1 invisible character | {"kIgnoreCase":false,"kUnicodeIgnoreCase":false,"sIgnoreCase":false,"sUnicodeIgnoreCase":false}{"kIgnoreCase":false,"kUnicodeIgnoreCase":true,"sIgnoreCase":false,"sUnicodeIgnoreCase":false} |
| Kelvin sign direct string / keep / invisible true | "K"U+212A | "K"No selected invisible characters found | {"kIgnoreCase":false,"kUnicodeIgnoreCase":true,"sIgnoreCase":false,"sUnicodeIgnoreCase":false}{"kIgnoreCase":false,"kUnicodeIgnoreCase":true,"sIgnoreCase":false,"sUnicodeIgnoreCase":false} |
| Long s direct string / keep / invisible true | "ſ"U+017F | "ſ"No selected invisible characters found | {"kIgnoreCase":false,"kUnicodeIgnoreCase":false,"sIgnoreCase":false,"sUnicodeIgnoreCase":true}{"kIgnoreCase":false,"kUnicodeIgnoreCase":false,"sIgnoreCase":false,"sUnicodeIgnoreCase":true} |
| Turkish dotted I direct string / keep / invisible true | "İ"U+0130 | "İ"No selected invisible characters found | {"kIgnoreCase":false,"kUnicodeIgnoreCase":false,"sIgnoreCase":false,"sUnicodeIgnoreCase":false}{"kIgnoreCase":false,"kUnicodeIgnoreCase":false,"sIgnoreCase":false,"sUnicodeIgnoreCase":false} |
The preserved visible character can match a different ASCII spelling
Each observer compares four anchored expressions: k and s, each with ignore-case alone and with Unicode plus ignore-case. A selected marker before the Kelvin sign prevents every anchored match. After deletion the plain visible Kelvin sign remains, and only the Unicode-aware k expression accepts it. The unmarked Kelvin reference already has that outcome. Long s likewise matches the Unicode-aware s expression while its ordinary ignore-case counterpart rejects it. Turkish dotted capital I matches neither selected letter expression in this matrix. All visible letters are retained by the cleaner. The change in the marked fixture is removal of an extra anchored character; the equivalence of Kelvin and k comes from the destination’s matching policy.
Regex folding is different from converting the stored string
No toUpperCase, toLowerCase or locale-sensitive mapping is called in this observer. The before and after strings remain available as exact code points, while the expressions decide a match without rewriting them. This distinguishes the result from our casing guides, which measure changed strings and their lengths, and from lookalike-letter inspection, which reports distinct code points. A matching result does not make the two stored spellings byte-identical. We do not enumerate all Unicode fold mappings, test a particular database index or establish a safe username policy. The flags and runtime are part of the fixture because another matching engine may implement a different contract. The Turkish control is a limit for these expressions, not a comprehensive test of Turkish case equivalence.
Keep equality, display and matching decisions explicit
If cleaned text unexpectedly matches a search term, capture the exact expression flags along with both spellings. Decide whether the destination wants Unicode case-insensitive matching or literal identity before treating a match as proof that a hidden character was converted. Our selected-marker case demonstrates that a deletion can reveal an existing equivalence even though the visible sign is untouched. Save the original data when a distinction matters for identifiers or integrity checks, and test that destination’s actual comparison operation. The downloadable code provides isolated local booleans and code points rather than a production access-control test. Do not use this small matrix to claim every visually similar character is equivalent or every ignore-case expression has the same behavior.
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.