Unicode normalization explained

Because Unicode can represent the same text multiple ways (precomposed vs combining marks), you often need to “normalize” it to a canonical form before comparing, searching or storing. There are four forms.

The four forms

FormDoesUse when
NFCComposes to shortest formGeneral text storage & comparison (most common)
NFDDecomposes into base + marksSome sorting/searching; stripping accents
NFKCComposes + compatibility foldingAggressive matching (fi→fi, ①→1)
NFKDDecomposes + compatibility foldingSearch indexing, loose matching

Canonical vs compatibility

Canonical forms (NFC/NFD) preserve meaning exactly. Compatibility forms (NFKC/NFKD) also fold “compatibility” characters — turning fi into “fi” or ① into “1” — which is great for search but loses formatting nuance. Don't use NFKC/NFKD where exact characters matter.

Practical rule

Normalize user input to NFC before storing or comparing, so “é” typed two different ways is treated as the same string.

input.normalize('NFC')

Frequently asked questions

Which normalization form should I use?

NFC for general storage and comparison. Use NFKC/NFKD only for loose search matching where folding is desired.

What does normalization fix?

It makes equivalent strings (e.g. precomposed vs combining-mark “é”) compare equal and sort predictably.