Recent chats
ASKGEEZ Q&A GUIDETechnology & devices

Why can two identical-looking strings compare as different Unicode text?

Quick answer

Two strings can look identical yet contain different Unicode code-point sequences. For example, ñ can be one code point or an n followed by a combining tilde; direct JavaScript string equality treats those sequences as different. Normalize both strings to a common form, such as NFC, before comparing when canonical equivalence is what you mean. Do not assume every system normalizes automatically, and use compatibility forms only when their broader changes fit your needs. [S1]

LET’S WORK THROUGH IT

The question, the details, the next step.

Question

Why does my exact text comparison say two strings are different when they look the same?

Geez

A visible character does not always correspond to just one code point. In JavaScript, ñ can be represented as U+00F1, or as U+006E followed by U+0303 (the letter n plus a combining tilde). The two sequences can render alike, but direct string equality treats them as different. [S1]

That distinction matters when a comparison is meant to recognize the same written character, rather than identical underlying sequences. Text from different sources may use different sequences. Appearance alone does not tell you whether the underlying sequences match, so inspect the values or normalize them before comparing.

Follow-up question

Can you show a small JavaScript example of the mismatch and a normalization-aware comparison?

Geez

Here is a minimal example. The first literal uses one code point for ñ; the second uses n followed by a combining tilde.

const a = "ñ";
const b = "n\u0303";

console.log(a === b); // false
console.log(a.normalize("NFC") === b.normalize("NFC")); // true

The normalize() method converts a string to a selected Unicode form. NFC and NFD put canonically equivalent sequences into a common form, so normalizing both values to the same form makes this kind of comparison possible. [S1] This example is about JavaScript; it does not mean every application, database, or programming language normalizes text automatically.

Follow-up question

Which normalization form should I choose, and could normalization change text I care about?

Geez

If you want canonically equivalent text to compare as equivalent, normalize both sides to the same form before comparing. NFC is one option; NFD is another form that puts canonically equivalent sequences into a common form. [S1]

NFKC and NFKD also fold some compatibility distinctions. That can change appearance, so those forms may not suit every purpose. [S1] Choose a form based on which distinctions your task should preserve, rather than assuming a compatibility form is always more thorough. The documented JavaScript method and normalization forms do not establish how a particular application stores, compares, or displays text.

Follow-up question

What should I check when this happens in my own data?

Geez

Start by narrowing down where the comparison fails, then compare a short example from each side. Check whether the code uses direct equality or normalizes both values to the same form first. If normalization resolves the mismatch, confirm that this matches the meaning you want: canonical equivalence, not necessarily every character that looks similar.

A reusable investigation note could look like this:

Field: [name of field]
Example A: [short text]
Example B: [short text]
Comparison used: [direct / normalized to NFC / other]
Observed result: [equal / not equal]
Expected result and reason: [brief explanation]

Use representative examples rather than changing all stored data based on one case. Check which component performs the comparison, too: this source describes JavaScript and does not establish behavior for other systems. [S1]

A practical checklist

  • Save a short example of each string that compares unexpectedly.

  • Confirm whether the comparison is direct equality or applies normalization.

  • If canonical equivalence is intended, normalize both strings to the same form, such as NFC, before comparing.

  • Check that a compatibility form is appropriate before using NFKC or NFKD, since it can change appearance.

  • Test representative cases in the actual system that performs the comparison; do not assume it normalizes text automatically.

A few more useful answers

Does NFC make every pair of visually similar strings equal?

No. NFC and NFD address canonically equivalent sequences; they are not a general rule for treating all visually similar text as equal. [S1]

Will JavaScript normalize strings automatically when I use `===`?

No. Direct equality treats the two ñ sequences as different. Call normalize() on both strings when that is the comparison you intend. [S1]

Should I use NFKC for every text comparison?

No. NFKC and NFKD fold some compatibility distinctions and may change appearance, so whether they fit depends on which distinctions your task should preserve. [S1]

Sources

References used for this guide.

  1. [S1] String.prototype.normalize() — JavaScript | MDN
    developer.mozilla.org · Checked

YOUR QUESTION. YOUR DETAILS.

Let’s work through your situation.

Get a tailored answer or help with your next task. Starts at $1, with a quote before you pay.

Ask your own question
← Back to Geez at Work