Invisible Character Detector

Two strings look identical, but VLOOKUP says they do not match. The import says "missing header" for a column that is clearly there. Paste the text and see what is actually in it.

🔒 Your text never leaves your browser.

Why "identical" strings do not match

Text carries passengers. A product title copied from a supplier's web page can contain a zero-width space in the middle of a word. A CSV saved by Excel starts with a byte-order mark that glues itself to the first column name. Word turns your apostrophes into curly ones and your hyphens into en dashes. None of it is visible — all of it changes the bytes.

The consequences are the bugs you have already met:

Not everything invisible should be deleted

A zero-width joiner in the middle of an emoji sequence is what makes the family emoji a single picture rather than three. Removing it corrupts the emoji. This tool reports those characters but leaves them alone when cleaning, and tells you which ones it kept and why — a blanket "strip all invisible characters" regex does not.

Characters this tool identifies (37 named, plus all full-width forms and control characters)

Zero-width characters

U+200B ZERO WIDTH SPACE

Where it comes from: Copied from web pages, or inserted by CMS editors as a line-break hint.

What it breaks: Splits a word invisibly. Exact-match lookups fail and search engines index a different string than the one you see.

Cleaning: deleted

U+200C ZERO WIDTH NON-JOINER

Where it comes from: Arabic, Persian and Indic text, where it controls letter shaping.

What it breaks: Meaningful in those scripts, but a stray one in Latin text breaks exact matching.

Cleaning: deleted

U+200D ZERO WIDTH JOINER

Where it comes from: Emoji sequences (family and profession emoji) and Indic scripts.

What it breaks: Removing it from an emoji sequence splits that emoji into several separate pictures.

Cleaning: left as-is (removing it could change meaning)

U+2060 WORD JOINER

Where it comes from: Typesetting tools preventing a line break at that position.

What it breaks: Invisible, but counts toward character and byte limits and breaks exact matching.

Cleaning: deleted

Byte-order mark

U+FEFF ZERO WIDTH NO-BREAK SPACE (byte-order mark)

Where it comes from: A byte-order mark left at the start of a UTF-8 file, usually by Excel or Notepad.

What it breaks: Attaches to the first column name, so the header "id" never matches "id" — the classic cause of "missing header" import errors.

Cleaning: deleted

Look-alike spaces

U+00A0 NO-BREAK SPACE

Where it comes from: Word, Google Docs and web pages ( ) — inserted automatically around units and after short words.

What it breaks: Looks exactly like a normal space but is a different character, so trimming and splitting on " " both miss it.

Cleaning: replaced with " "

U+202F NARROW NO-BREAK SPACE

Where it comes from: French typography and some spreadsheet locales, where it is the thousands separator.

What it breaks: Invisibly different from a normal space; breaks numeric parsing and matching.

Cleaning: replaced with " "

U+3000 IDEOGRAPHIC SPACE

Where it comes from: CJK input methods — the full-width space.

What it breaks: Twice as wide as a normal space, and not removed by trim() in some tools.

Cleaning: replaced with " "

U+2007 FIGURE SPACE

Where it comes from: Numeric tables where digits must align.

What it breaks: Not a normal space; breaks number parsing.

Cleaning: replaced with " "

U+2009 THIN SPACE

Where it comes from: Typesetting and PDF text extraction.

What it breaks: Not a normal space; breaks splitting and matching.

Cleaning: replaced with " "

Smart quotes

U+2018 LEFT SINGLE QUOTATION MARK

Where it comes from: Word and Google Docs autocorrect.

What it breaks: Breaks CSV quoting and code that expects a straight apostrophe.

Cleaning: replaced with "'"

U+2019 RIGHT SINGLE QUOTATION MARK

Where it comes from: Word and Google Docs autocorrect — the "smart apostrophe".

What it breaks: Breaks CSV quoting and exact matching on names containing apostrophes.

Cleaning: replaced with "'"

U+201C LEFT DOUBLE QUOTATION MARK

Where it comes from: Word and Google Docs autocorrect.

What it breaks: Not a CSV quote character, so quoting fails in ways that are hard to trace.

Cleaning: replaced with """

U+201D RIGHT DOUBLE QUOTATION MARK

Where it comes from: Word and Google Docs autocorrect.

What it breaks: Not a CSV quote character, so quoting fails in ways that are hard to trace.

Cleaning: replaced with """

Look-alike dashes

U+2013 EN DASH

Where it comes from: Word autocorrect turning "1-2" into "1–2".

What it breaks: Not a hyphen — SKU and range matching fails.

Cleaning: replaced with "-"

U+2014 EM DASH

Where it comes from: Word autocorrect turning "--" into "—".

What it breaks: Not a hyphen; breaks identifier matching.

Cleaning: replaced with "-"

U+2212 MINUS SIGN

Where it comes from: Spreadsheets and mathematical typesetting.

What it breaks: Looks like a hyphen-minus but is a different character; breaks numeric parsing.

Cleaning: replaced with "-"

U+00AD SOFT HYPHEN

Where it comes from: Word processors marking where a word may be hyphenated.

What it breaks: Invisible until the text wraps, then a hyphen appears from nowhere. Breaks exact matching in the meantime.

Cleaning: deleted

Exotic line breaks

U+0085 NEXT LINE (NEL)

Where it comes from: Mainframe and legacy EBCDIC exports.

What it breaks: Treated as a line break by some parsers and not others, so rows split unpredictably.

Cleaning: replaced with " "

U+2028 LINE SEPARATOR

Where it comes from: Shift+Enter in some editors, and JSON copied out of JavaScript.

What it breaks: Breaks a CSV row in half in some parsers and is invisible in others.

Cleaning: replaced with " "

U+2029 PARAGRAPH SEPARATOR

Where it comes from: Word and rich-text conversion.

What it breaks: Same as the line separator — unpredictable row splitting.

Cleaning: replaced with " "

Bidirectional controls

U+202A LEFT-TO-RIGHT EMBEDDING

Where it comes from: Mixed Arabic/Hebrew and Latin text.

What it breaks: Invisible, but makes displayed text differ from stored text. Must be closed by U+202C.

Cleaning: deleted

U+202B RIGHT-TO-LEFT EMBEDDING

Where it comes from: Mixed Arabic/Hebrew and Latin text.

What it breaks: Invisible, but makes displayed text differ from stored text. Must be closed by U+202C.

Cleaning: deleted

U+202C POP DIRECTIONAL FORMATTING

Where it comes from: Written by editors and libraries that emit bidirectional text, to close an embedding or override they opened.

What it breaks: Harmless on its own, but one too many means an embedding was closed that was never opened.

Cleaning: deleted

U+202D LEFT-TO-RIGHT OVERRIDE

Where it comes from: Almost never legitimate in product data.

What it breaks: Forces display order regardless of the characters — the same mechanism as U+202E, in the other direction.

Cleaning: deleted

U+202E RIGHT-TO-LEFT OVERRIDE

Where it comes from: Almost never legitimate in product data.

What it breaks: Reverses the display order of everything after it — a known trick for disguising file names and text. Treat its presence as suspicious.

Cleaning: deleted

U+2066 LEFT-TO-RIGHT ISOLATE

Where it comes from: Modern replacement for the embedding controls.

What it breaks: Isolates the run that follows from surrounding text. Must be closed by U+2069.

Cleaning: deleted

U+2067 RIGHT-TO-LEFT ISOLATE

Where it comes from: Modern replacement for the embedding controls.

What it breaks: Isolates the run that follows from surrounding text. Must be closed by U+2069.

Cleaning: deleted

U+2068 FIRST STRONG ISOLATE

Where it comes from: Used when the direction of the inserted text is not known in advance.

What it breaks: Isolates the run that follows, taking its direction from its first strong character. Must be closed by U+2069.

Cleaning: deleted

U+2069 POP DIRECTIONAL ISOLATE

Where it comes from: Written by editors and libraries that emit bidirectional text, to close an isolate they opened.

What it breaks: Harmless on its own, but one too many means an isolate was closed that was never opened.

Cleaning: deleted

U+200E LEFT-TO-RIGHT MARK

Where it comes from: Inserted by editors to pin the direction of neighbouring punctuation.

What it breaks: Legitimate in genuinely bidirectional text, but invisible — so it silently makes two otherwise identical strings unequal.

Cleaning: deleted

U+200F RIGHT-TO-LEFT MARK

Where it comes from: Inserted by editors to pin the direction of neighbouring punctuation.

What it breaks: Legitimate in genuinely bidirectional text, but invisible — so it silently makes two otherwise identical strings unequal.

Cleaning: deleted

Control characters

U+0009 CHARACTER TABULATION (tab)

Where it comes from: Copied from spreadsheets or code.

What it breaks: Splits a TSV field in two — one stray tab shifts every later column on that row.

Cleaning: replaced with " "

U+000B LINE TABULATION (vertical tab)

Where it comes from: Shift+Enter in Word, and some PDF extractors.

What it breaks: Acts as a line break in some tools and as nothing in others.

Cleaning: replaced with " "

U+000C FORM FEED

Where it comes from: Legacy printing control, occasionally left by PDF extraction.

What it breaks: Invisible; corrupts field parsing.

Cleaning: replaced with " "

Variation selectors

U+FE0F VARIATION SELECTOR-16

Where it comes from: Emoji — forces the colourful rendering of a symbol.

What it breaks: Invisible, counts toward length limits, and turns an otherwise plain symbol into an emoji that many marketplaces reject.

Cleaning: left as-is (removing it could change meaning)

U+FE0E VARIATION SELECTOR-15

Where it comes from: Emoji — forces the monochrome text rendering.

What it breaks: Invisible but stored, and counts toward length limits.

Cleaning: left as-is (removing it could change meaning)