Normalization — two spellings of é that === calls different¶
Level: 201 · for anyone comparing text that came from somewhere else
Stub — an outline, not a lesson. There is no runnable example behind this page yet, so nothing on it has been through the check that backs every other claim in this library. The questions below are what the finished page has to answer.
One line: "\u{E9}" and "e\u{301}" both show as é, yet === is false, their lengths are 1 and 2, and a Set keeps both; normalize("NFC") on each side makes them equal, while localeCompare already returns 0 for the pair.
Keywords: normalize, NFC, NFD, NFKC, NFKD
What the finished page will answer¶
- Why is
"\u{E9}" === "e\u{301}"false, and what are the two lengths? - What do NFC, NFD, NFKC and NFKD turn
é,fi,①and the Angstrom sign U+212B into? - Why does
localeComparereturn0for the two spellings when===,SetandMaptreat them as different? - Where should a program normalize: on input, before comparing, or before using a string as a key?
- How do you strip accents with
normalize("NFD")and a\p{M}regex, and why doesøcome through unchanged?
Examples it will need¶
-
normalization_forms_js.js—é,fi,①and U+212B through NFC, NFD, NFKC and NFKD, with the code points of each result -
normalization_lookup_js.js— aMapkeyed by the composedcafémissing the decomposed one, finding it once both are normalized, andlocaleComparereturning0without normalizing
See also¶
- Comparing and sorting strings —
localeCompare, which already treats the two spellings as equal - Graphemes — one visible character made of several code points
===and==— what===compares when both sides are stringsMapandSet— why aSetkeeps both spellings as different members- Encodings: Normalization ↗ — the four forms, run in Python
- Java text: Normalization and equality ↗ — in Java,
equalshas the same blind spot - Encodings: The check that ran too early ↗ — the security bug of checking a string before normalizing it