Skip to content

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 localeCompare return 0 for the two spellings when ===, Set and Map treat 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 — a Map keyed by the composed café missing the decomposed one, finding it once both are normalized, and localeCompare returning 0 without normalizing

See also

Sources to start from