Zero-Width Characters Survive str.strip() in Python (tested)
Pasted text sometimes carries invisible characters like zero-width space -- they take up zero width on screen, so two strings can look pixel-for-pixel identical while one has an extra, invisible character. We measured whether str.strip() removes them. It doesn't, and the reason is specific: Python's whitespace definition is based on Unicode category, and zero-width characters aren't in it.
1. str.strip() leaves a trailing zero-width space in place
zwsp = "\u200b"
clean = "hello"
dirty = "hello" + zwsp
print(clean, "/", dirty)
print(clean == dirty)
print(dirty.strip() == clean)
print(repr(dirty.strip()))
hello / hello
False
False
'hello\u200b'
Measured: dirty prints as plain hello -- the zero-width space is, by definition, invisible -- but it's a real character, so == correctly returns False. The surprise is that .strip() doesn't fix it either: the character comes back unchanged in the output, because strip() with no arguments only removes characters Python classifies as whitespace, and zero-width space isn't one of them.
2. The reason: its Unicode category is Format (Cf), not Space (Zs)
import unicodedata
for ch in ["\u200b", "\u200c", "\u200d", "\ufeff", "\xad"]:
print(unicodedata.name(ch), "->", unicodedata.category(ch), "isspace():", ch.isspace())
ZERO WIDTH SPACE -> Cf isspace(): False
ZERO WIDTH NON-JOINER -> Cf isspace(): False
ZERO WIDTH JOINER -> Cf isspace(): False
ZERO WIDTH NO-BREAK SPACE -> Cf isspace(): False
SOFT HYPHEN -> Cf isspace(): False
Measured: every zero-width character we checked is category Cf ("Format"), and str.isspace() returns False for all of them. Compare that to actual whitespace: regular space and tab are categories Zs/Cc, and both strip() and isspace() handle them correctly, along with less obvious ones like non-breaking space (\xa0) and em space (\u2003), which are category Zs and do get stripped.
3. Ordinary whitespace, for contrast, strips cleanly
import unicodedata
for ch in [" ", "\t", "\n", "\xa0", "\u2003"]:
padded = ch + "hello" + ch
print(repr(ch), unicodedata.category(ch), "stripped clean:", padded.strip() == "hello")
' ' Zs stripped clean: True
'\t' Cc stripped clean: True
'\n' Cc stripped clean: True
'\xa0' Zs stripped clean: True
'\u2003' Zs stripped clean: True
Measured: all five of these strip cleanly, including the two that are easy to miss visually (non-breaking space and em space) -- Python's strip() already handles the full range of actual whitespace categories correctly. Zero-width characters are a different problem entirely: they're invisible like whitespace, but they're semantically "format" characters (used for things like controlling Arabic/Indic text shaping), so no amount of calling strip() will remove them. If you need to clean pasted or user-submitted text, strip zero-width characters explicitly, e.g. "".join(c for c in s if unicodedata.category(c) != "Cf"), rather than relying on strip() or isspace().
Frequently asked questions
Does Python's str.strip() remove zero-width spaces?
No -- we measured this directly: a trailing U+200B (ZERO WIDTH SPACE) survives .strip() unchanged, because strip() only removes characters in Unicode's whitespace categories, and zero-width space isn't one of them.
What Unicode category is zero-width space?
Cf, 'Format' -- we confirmed this for ZERO WIDTH SPACE, ZERO WIDTH NON-JOINER, ZERO WIDTH JOINER, ZERO WIDTH NO-BREAK SPACE, and SOFT HYPHEN. None of them are in the Zs (space) or Cc (control) categories that strip() and isspace() actually check.
Why can two identical-looking strings fail == in Python?
One may contain an invisible Unicode character like zero-width space that the other doesn't. We measured this directly: both strings print identically, but == correctly returns False because the characters are genuinely different.
Does str.isspace() return True for zero-width characters?
No -- we measured isspace() returning False for every zero-width character we tested, which is consistent with strip() also leaving them in place; both functions are driven by the same whitespace-category definition.
How do I actually remove zero-width characters from a string in Python?
Filter by Unicode category explicitly, e.g. \"\".join(c for c in s if unicodedata.category(c) != \"Cf\"). We confirmed strip() alone does not remove them, since they fall outside the categories it checks.
Written with AI assistance. Measured on 2026-10-04 with Python 3.13.5's built-in unicodedata module: built strings containing zero-width Unicode characters (ZERO WIDTH SPACE U+200B and others), checked their unicodedata category, and tested str.strip() and str.isspace() against them, contrasted with ordinary whitespace characters (space, tab, non-breaking space, em space). PlainHeaders is our extension; Python's unicodedata module is built in.