Tabellab
Data, tech, science & health

Fuzzy matching in Excel with Jaccard similarity

Jaccard similarity is the size of the overlap of two sets divided by the size of their union: shared ÷ (A + B − shared). For fuzzy matching names, the sets are usually the character bigrams (pairs of neighbouring letters), which Excel cuts with MID(A2,SEQUENCE(LEN(A2)-1),2). A typo barely moves the score: "brightline office supply" and "brightline ofice supply" share 22 bigrams and score 0.957, while "acme tools" and "apex tools" score only 0.385. This guide builds the formula step by step, compares it with Dice and word-level Jaccard, and shows why a threshold alone sent "summit dental" and "summit rental" to review instead of a match.

Updated 21 Oct 2026 6 min read By Tabellab team

The Jaccard similarity formula

J(A, B) = |A ∩ B| ÷ |A ∪ B| = shared ÷ (|A| + |B| − shared)

The result runs from 0 (nothing in common) to 1 (identical sets). For text, you first decide what the elements of the set are: whole words (tokens) or short pieces of characters (n-grams). Bigrams, pieces of two characters, are the usual choice for names, because a typo only spoils the one or two bigrams around it while the rest still match. Take "acme tools" and "apex tools". Each has 9 bigrams (a text of length L has L − 1), and 5 are shared: " t", "to", "oo", "ol" and "ls". Jaccard = 5 ÷ (9 + 9 − 5) = 5 ÷ 13 = 0.385. The shared word "tools" is not enough to call them the same company.

Bigram Jaccard in Excel, step by step

With the two normalised names in A2 and B2:

  • MID(A2,SEQUENCE(LEN(A2)-1),2) returns all bigrams of A as an array: SEQUENCE gives the start positions 1, 2, 3 … and MID takes two characters from each.
  • MATCH(bigrams of A, bigrams of B, 0) looks up each bigram of A in B, ISNUMBER turns found into TRUE, and SUM(--…) counts them: the shared bigrams in column C.
  • Jaccard in column D: =C2/(LEN(A2)-1+LEN(B2)-1-C2).

With LET it fits in one readable formula: =LET(ga,MID(A2,SEQUENCE(LEN(A2)-1),2), gb,MID(B2,SEQUENCE(LEN(B2)-1),2), s,SUM(--ISNUMBER(MATCH(ga,gb,0))), s/(ROWS(ga)+ROWS(gb)-s)). Strictly, Jaccard is defined on sets of distinct elements. This count-based version counts a repeated bigram of A each time, which is close enough for company names and is what many matching tools do. Whichever definition you use, use it consistently and set thresholds on it.

Worked example: bigram Jaccard and Dice for ten pairs of company names

Columns A and B hold ten pairs of normalised company names (lower case, punctuation removed). Column C counts the bigrams of name A that also occur in name B, columns D and E turn the count into the Jaccard and Dice similarity, and column F applies the two thresholds in F13 and F14. Rows 19 to 21 compare the word-level Jaccard for three pairs.

Worked example: bigram Jaccard and Dice for ten pairs of company names
ABCDEF
1Name AName BShared bigramsJaccardDiceDecision
2brightline office supplybrightline ofice supply220.9570.978Match
3harbor print coharbour print co130.8130.897Match
4maple law groupmaple law grp110.7330.846Review
5coral realtycoral reality100.7690.870Match
6north ridge cafenorthridge cafe130.8130.897Match
7delta logisticsdelta logistic130.9290.963Match
8jones and smithsmith and jones120.7500.857Match
9willow pharmawillow farms80.5330.696Review
10summit dentalsummit rental100.7140.833Review
11acme toolsapex tools50.3850.556Non-match
12
13Match threshold (Jaccard at least)0.75
14Review threshold (Jaccard at least)0.50
15Pairs scored Match6
16Pairs sent to Review3
17Pairs scored Non-match1
18Bigrams in "brightline office supply" (length − 1)23
19Word Jaccard, row 8 (same words, new order)1.000
20Word Jaccard, row 9 (one shared word of three)0.333
21Word Jaccard, row 6 (north ridge vs northridge)0.250
Key formulas
  • C2=SUM(--ISNUMBER(MATCH(MID(A2,SEQUENCE(LEN(A2)-1),2),MID(B2,SEQUENCE(LEN(B2)-1),2),0)))Bigrams of A that also occur in B
  • D2=C2/(LEN(A2)-1+LEN(B2)-1-C2)Jaccard = shared ÷ (bigrams A + bigrams B − shared)
  • E2=2*C2/(LEN(A2)-1+LEN(B2)-1)Dice = 2 × shared ÷ (bigrams A + bigrams B)
  • F2=IF(D2>=$F$13,"Match",IF(D2>=$F$14,"Review","Non-match"))Two thresholds, three decisions
  • F19=SUM(--ISNUMBER(XMATCH(TEXTSPLIT(A8," "),TEXTSPLIT(B8," "))))/(COUNTA(TEXTSPLIT(A8," "))+COUNTA(TEXTSPLIT(B8," "))-SUM(--ISNUMBER(XMATCH(TEXTSPLIT(A8," "),TEXTSPLIT(B8," ")))))Word-level (token) Jaccard

Fictional company names. MID with SEQUENCE and TEXTSPLIT need Microsoft 365 or Excel 2021 and later (TEXTSPLIT: Microsoft 365 and Excel 2024). The thresholds are illustrative: set your own from a labelled sample.

Normalise before you compare

Similarity scores only measure what is left after cleaning. "Harbor Print Co., Inc." and "HARBOR PRINT CO" differ in case, punctuation and a legal suffix, none of which tells you anything about the customer. Clean both columns first: LOWER and TRIM for case and spaces, SUBSTITUTE for punctuation, and a short list of legal suffixes (inc, llc, ltd, gmbh) to strip. The example uses names that were already normalised that way. Without that step, exact duplicates can score below 0.8 and the thresholds stop meaning anything.

Jaccard vs Dice vs word-level Jaccard

The Dice coefficient = 2 × shared ÷ (bigrams A + bigrams B) uses the same counts and always gives the same ranking, but higher numbers: 0.556 instead of 0.385 for "acme tools". Do not mix the two when you set thresholds.

Word-level Jaccard compares whole words with TEXTSPLIT(A2," ") instead of bigrams. It handles reordering perfectly: "jones and smith" vs "smith and jones" scores 1.000 on words but only 0.750 on bigrams. It fails on a missing space: "north ridge cafe" vs "northridge cafe" shares only "cafe" and scores 0.250 on words, against 0.813 on bigrams. And it overrates different businesses with shared words: "willow pharma" vs "willow farms" scores 0.333 on words and 0.533 on bigrams. Each score catches different errors, which is why matching tools combine several. For vector-style comparisons of longer texts, see cosine similarity in Excel.

Thresholds: match, review, non-match

One threshold forces every pair into yes or no. Two thresholds create a middle band for a human to check: in the example, a Jaccard of at least 0.75 is a Match, 0.5 to 0.75 goes to Review, and anything lower is a Non-match. That gives 6 matches, 3 reviews and 1 non-match. The review band catches the hard cases: "maple law grp" (0.733) is the same firm with an abbreviation, but "summit dental" vs "summit rental" (0.714) and "willow pharma" vs "willow farms" (0.533) are different businesses with similar names. A lower match threshold of 0.7 would have merged the dentist with the rental company.

Set thresholds from data, not by feel: label a sample of pairs by hand, then measure precision and recall at several cut-offs and pick the trade-off that fits the cost of a wrong merge.

Scaling up: blocking keys

Comparing every record with every other grows fast: 10,000 customers make almost 50 million pairs, far too many for array formulas. Real record linkage first builds a blocking key, for example the first letter of the name plus the postcode, and only compares records inside the same block. That cuts the pairs by orders of magnitude, at the risk of missing duplicates whose key differs (a typo in the first letter). Score the candidate pairs with bigram Jaccard, add other evidence such as matching phone numbers or addresses, and merge the confirmed duplicates into one golden record.

Common mistakes

  • Scoring raw names. Case, punctuation and "Inc." lower the score of real duplicates. Normalise both columns before comparing.
  • Mixing Jaccard and Dice thresholds. Dice is always higher for the same pair. A 0.75 threshold means different things in each.
  • One threshold for everything. Similar names of different businesses land just above any single cut-off. Add a review band.
  • Bigrams on very short strings. "ab" has one bigram, so one typo drops the score to 0. Use exact or word matching for codes and short names.
  • Comparing every pair. All-against-all comparison explodes with list size. Block on a key first.
  • Guessing the cut-off. Measure precision and recall on hand-labelled pairs before trusting the matcher.

Frequently asked questions

How do you do fuzzy matching in Excel?

Normalise both lists with LOWER, TRIM and SUBSTITUTE, then score each candidate pair with a similarity measure such as bigram Jaccard: =LET(ga,MID(A2,SEQUENCE(LEN(A2)-1),2),gb,MID(B2,SEQUENCE(LEN(B2)-1),2),s,SUM(--ISNUMBER(MATCH(ga,gb,0))),s/(ROWS(ga)+ROWS(gb)-s)). Pairs above a threshold are treated as matches. Power Query also has a built-in fuzzy merge.

What is a good Jaccard similarity score?

It depends on the data and the elements you compare. For normalised company names on character bigrams, real duplicates with a typo typically score above 0.75, but similar names of different businesses can score 0.7 too. Set thresholds from a labelled sample.

What is the difference between Jaccard and Dice similarity?

Jaccard divides the shared elements by the union, shared ÷ (A + B − shared). Dice divides twice the shared elements by the sum of both sizes. They rank pairs identically, but Dice gives higher values.

Does Excel have a fuzzy match function?

There is no worksheet function for fuzzy matching. Power Query offers a fuzzy merge with a similarity threshold, and the Fuzzy Lookup add-in exists for older versions. With Microsoft 365 you can build a transparent similarity score with MID, SEQUENCE and MATCH.

Practise it in a lab

Related guides

Reading is step one. Doing is step two.

Every guide links to a lab where you build the same calculation in an online spreadsheet and get instant feedback.

Open the lab