Invisible Character Remover — Detect and Remove Invisible Characters
Paste your text and see every hidden code point named, counted, and explained — then get a clean copy with all of them stripped out.
Hidden character report
Paste text to scan
What invisible characters are
Unicode assigns code points to characters that have no visible glyph. They exist because text rendering is more complicated than it looks: scripts run in different directions, emoji are built from sequences of simpler parts, and words need hints about where they can break. These characters do real work inside a renderer. Outside of one, they are usually noise.
The phrase "invisible character" covers several distinct families. Zero-width characters take no space and leave no mark. Format controls steer the direction or joining behaviour of adjacent glyphs. Invisible spaces look like gaps but behave differently from an ordinary space character. Each family has a different origin, a different failure mode, and a different cleanup rule.
The full roster: nine character types worth knowing
U+200B ZERO WIDTH SPACE is the most common offender. Chat interfaces insert it between tokens to hint at line-break points; copy the answer and it travels with every word boundary. Databases, search indexes and code string comparisons all treat it as a distinct character.
U+200C ZERO WIDTH NON-JOINER and U+200D ZERO WIDTH JOINER control ligature formation. ZWNJ prevents two adjacent characters from forming a ligature (important in Persian and Hindi); ZWJ forces them to join (used inside emoji sequences like family glyphs and flag pairs). Both are invisible and both survive a paste into plain text.
U+FEFF BYTE ORDER MARK was designed as a file-encoding hint placed once at the start of a stream. Rich-text editors — particularly older versions of Microsoft Word and some CMS paste handlers — inject it mid-document whenever they receive pasted content, where it is simply an invisible placeholder that breaks string comparisons.
U+2060 WORD JOINER behaves like a zero-width space but also signals that the two surrounding characters must not be separated by a line break. A renderer in a chat interface inserts it around short words or numbers to prevent awkward wrapping; once copied into a database field, it silently corrupts prefix searches.
U+00AD SOFT HYPHEN is visible only when it falls at an active line-break point. A word processor that auto-hyphenates inserts it everywhere it decides a word could break. Paste such a paragraph into a web form and every potential hyphen point travels along, inflating character counts and fouling validation.
U+180E MONGOLIAN VOWEL SEPARATOR was originally used in Mongolian script to separate vowel sequences. It was briefly assigned zero-width-space behaviour in some Unicode versions, then reclassified. Several OCR tools and legacy encoders still emit it; modern text engines render it as nothing, but it occupies a code point that breaks exact-match queries.
U+3164 HANGUL FILLER is a placeholder used in Korean input methods to hold the cursor position while a syllable block is being composed. It looks like a space but has a distinct code point. It occasionally escapes into clipboard content when text is copied mid-composition, and it is wide enough to be mistaken for an ordinary ideographic space.
U+00A0 NO-BREAK SPACE and U+202F NARROW NO-BREAK SPACE look like spaces and are often intended as spaces — the difference is that they will not allow a line break at that position. A title with a no-break space between the last two words will overflow its container instead of wrapping. This tool normalises them to ordinary spaces rather than deleting them, to avoid silently joining two words.
Tabs (U+0009) and non-breaking spaces are not always invisible in the sense of zero-width, but they are invisible in the sense of indistinguishable from a regular space in most views. A cell in Excel that begins with a tab character is treated as text regardless of its contents. A SQL WHERE clause comparing a string with a trailing U+00A0 will miss every row stored without it.
Where they come from
Chat interfaces are the largest single source today. Streamed answers are assembled fragment by fragment; the renderer adds zero-width joiners to hold emoji sequences together, word joiners around numbers, and zero-width spaces at word boundaries. Press the copy button and the whole layer comes with you.
Word processors are the second source. Microsoft Word inserts soft hyphens when it auto-hyphenates; older versions insert BOM markers on paste. LibreOffice has its own set of invisible markers for tracked changes and comment anchors. Copy a paragraph from any of them into a browser form and you bring those markers along.
OCR pipelines frequently emit U+180E and U+FEFF as artefacts of format conversion. PDF-to-text extractors disagree on how to represent ligatures and may insert zero-width joiners where the original PDF had a single glyph. Korean input methods leave U+3164 fillers when composition is interrupted.
Some developers deliberately insert invisible characters — most often U+200B — to mark text ownership, detect copying, or signal metadata. That is a legitimate technique in its original context. The problem is the same as with accidental characters: once the text leaves that context, the markers persist wherever the text goes.
Why they cause real failures
Form validation is the most reported pain point. An email address field that passes a client-side regex fails the mail server's own check because there is a U+200B between the local part and the domain. A phone number field that looks correct contains a soft hyphen the validator does not expect. Both failures are hard to debug because the display shows nothing wrong.
Excel and Google Sheets have their own set of quirks. A numeric cell that starts with U+FEFF is classified as text, so SUM ignores it. A VLOOKUP that should match a product code misses every row because the lookup key was copied from a chat window with zero-width spaces intact. Sorting a column that mixes BOM-prefixed and clean cells produces an ordering that appears random.
SQL queries fail silently. A WHERE name = 'Alice' clause returns no rows if the stored value has a U+200C between the 'l' and the 'i'. The value looks correct in every admin panel and database browser, because every admin panel and database browser renders it as a visible string.
Code diffs report spurious changes. A git diff that shows a whole line as modified — when only one invisible character moved — breaks code review. The reviewer sees what looks like a no-op change and either approves it without scrutiny or asks a question nobody can answer from the diff alone.
Search indexes miss the phrase. A full-text index that tokenises on whitespace and punctuation treats a zero-width space as a token boundary. The word you indexed is two tokens; the word you searched for is one. No match.
Word count tools overcount. Soft hyphens are characters; a word processor that counts characters counts them. A document that looks like 1 000 words may report 1 024 because of soft hyphens auto-inserted during editing.
How to detect invisible characters without this tool
Three browser-console lines cover the most common check. Open the console, paste your string into a variable, and call 'yourstring'.split('').map((c, i) => [i, c.charCodeAt(0).toString(16), c]).filter(([, code]) => parseInt(code, 16) > 127 || parseInt(code, 16) < 32). Any row with a code point outside the printable ASCII range is worth investigating.
On the command line, xxd yourfile.txt | less shows the raw hex stream. U+200B appears as e2 80 8b in UTF-8; U+FEFF as ef bb bf. The grep -P flag accepts Perl-compatible regular expressions, so grep -P '[\x{200B}\x{FEFF}]' yourfile.txt will list every matching line.
Pasting into this tool is faster for most cases. The report panel shows each code point by name, with a count, so you see at a glance whether the problem is one stray BOM or ten thousand zero-width spaces spread through an entire document.
How to clean them out and what stays intact
Paste your text and press Clean. The engine reads each Unicode code point in order — not bytes, not code units — and removes any that match the published table. U+200B, U+200C, U+200D, U+FEFF, U+2060, U+00AD, U+180E and U+3164 are deleted. U+00A0 and U+202F are converted to ordinary spaces, because deleting a no-break space between two words would silently join them.
Everything else is unchanged: letters, digits, punctuation, emoji, tabs, ordinary line breaks, paragraph order. The engine does not rewrite sentences, normalise typography or guess at intent. It removes a defined set of characters and reports exactly what it removed.
For text that has come through multiple applications, the report is often the more useful output. If every paragraph reports the same mix of BOM markers and zero-width spaces, the source is a specific pipeline step — and fixing that step upstream is more efficient than cleaning each document afterwards.
Internal links: for a focused look at zero-width characters specifically, the <a href="/zero-width-space-remover">zero width space remover</a> page covers the six zero-width code points in depth. For removing general AI text artefacts, see <a href="/clean-ai-text">clean AI text</a>. For the full invisible-character check plus a watermark discussion, the <a href="/chatgpt-watermark-remover">ChatGPT watermark remover</a> page has that context.
Characters this tool looks for
25 invisible characters and formatting controls, with the action taken on each one.
| Character | Code point | Action | What it does |
|---|---|---|---|
| Zero-width characters | |||
| Zero Width Space | U+200B | Removed | Invisible separator with no width. Commonly left behind when text is copied out of a chat window. |
| Zero Width Non-Joiner | U+200C | Removed | Invisible character that blocks two letters from joining in scripts such as Arabic or Devanagari. |
| Zero Width Joiner | U+200D | Removed | Invisible character used to glue emoji sequences together. Stray copies can break word wrapping. |
| Zero Width No-Break Space (BOM) | U+FEFF | Removed | Byte order mark. Harmless at the start of a file, invisible noise anywhere else. |
| Word Joiner | U+2060 | Removed | Tells a text engine not to break a line here. Invisible, and easy to carry along by accident. |
| Mongolian Vowel Separator | U+180E | Removed | A legacy invisible separator from Mongolian script that now renders as nothing at all. |
| Bidirectional controls | |||
| Left-to-Right Mark | U+200E | Removed | Directional hint for mixed-script lines. Invisible on screen but present in the character stream. |
| Right-to-Left Mark | U+200F | Removed | Mirror of the left-to-right mark, used to steer the order of mixed-direction text. |
| Arabic Letter Mark | U+061C | Removed | Invisible directional marker for Arabic text. Rarely intentional outside its original document. |
| Left-to-Right Embedding | U+202A | Removed | Opens an embedded left-to-right run. Unpaired copies can scramble the order of a sentence. |
| Right-to-Left Embedding | U+202B | Removed | Opens an embedded right-to-left run. Left behind after copy-paste, it can flip nearby punctuation. |
| Pop Directional Formatting | U+202C | Removed | Closes an embedded directional run. Without its partner it is pure invisible noise. |
| Left-to-Right Override | U+202D | Removed | Forces following characters to display left-to-right regardless of their own direction. |
| Right-to-Left Override | U+202E | Removed | Forces following characters to display right-to-left. A common cause of text that looks reversed. |
| Left-to-Right Isolate | U+2066 | Removed | Modern replacement for the embedding controls. Still invisible, still travels with copied text. |
| Right-to-Left Isolate | U+2067 | Removed | Isolates a right-to-left run from the surrounding paragraph direction. |
| First Strong Isolate | U+2068 | Removed | Isolates a run whose direction is decided by its first strong character. |
| Pop Directional Isolate | U+2069 | Removed | Closes an isolate opened by one of the isolate controls above. |
| Formatting controls | |||
| Soft Hyphen | U+00AD | Removed | A hyphen the reader only sees if the word happens to break at the end of a line. |
| Carriage Return (CR) | U+000D | Removed | Half of a Windows line ending. Kept on its own it produces doubled spacing in most editors. |
| Markdown Asterisk Marker | U+002A | Removed | Bold or italic marker such as ** left behind when text is copied in its raw form. Turn this group off to keep Markdown styling marks. |
| Markdown Backtick Marker | U+0060 | Removed | Inline-code backtick left behind after copying raw assistant output. Turn this group off to keep inline code marks. |
| Invisible spaces | |||
| No-Break Space | U+00A0 | → space | Looks exactly like a space but stops a line from breaking there. A frequent copy-paste leftover. |
| Figure Space | U+2007 | → space | A space as wide as a digit, used to align numbers in tables. Replaced with a normal space. |
| Narrow No-Break Space | U+202F | → space | A thin, non-breaking space from French typography. Replaced with a normal space. |
Frequently Asked Questions
▸Are invisible characters dangerous — a virus or some kind of attack?
No. An invisible character is a data character, the same category as a comma or a letter. It cannot execute code, escalate permissions or replicate itself. Some invisible characters are used in homograph attacks — a domain name that looks like a known brand but contains a visually identical character from a different script — but that is a phishing technique, not the character itself doing anything harmful. Removing invisible characters from plain text cleans up formatting artefacts; it does not defend against anything.
▸Will removing invisible characters break my emoji or special characters?
Emoji sequences use U+200D (ZWJ) to combine simpler glyphs into family or profession emoji. This tool removes ZWJ, which may split a combined emoji into its component parts — for example, a family emoji may become three separate person glyphs. If you are working with emoji-heavy content and the combinations matter, check the report before copying. Every other visible character — accented letters, currency symbols, CJK characters, mathematical notation — passes through unchanged.
▸My text looks identical before and after cleaning. Did anything actually change?
Check the report panel underneath the output. It lists every code point that was removed, with a count. If the report shows rows, characters were removed even though the display looks the same — that is the definition of invisible. If the report is empty, your text contained none of the characters in the table, and the input and output really are byte-for-byte identical.