Excel professionals often struggle to extract precise data when case sensitivity matters in unsorted datasets. While standard lookup functions like basic VLOOKUP or INDEX/MATCH are excellent for general queries, they notoriously ignore letter casing. Implementing a specialized array formula grants complete retrieval precision by distinguishing exact character cases. However, this approach carries the stipulation that you must nest the EXACT function within your search array to avoid false positives-such as treating "ID-99a" and "ID-99A" as identical. Below, we outline the exact formula syntax and step-by-step logic to execute this advanced lookup.
Excel is an incredibly powerful tool for data analysis, but it has a few built-in behaviors that can frustrate users. One of the most common stumbling blocks is its default case-insensitivity. By default, standard lookup functions like VLOOKUP, HLOOKUP, MATCH, and even the modern XLOOKUP do not distinguish between lowercase and uppercase letters. To these functions, "APPLE", "apple", and "aPpLe" are entirely identical.
This behavior becomes problematic when you work with system-generated exports, product codes, inventory SKUs, passwords, or transactional data where letter casing differentiates distinct records. The challenge is amplified when your dataset is unsorted, preventing you from using binary search workarounds. To perform a case-sensitive lookup on unsorted data, you must combine Excel's lookup engines with a dedicated text-comparison function.
In this guide, we will explore how to build robust, case-sensitive lookup formulas using classic Excel methods (INDEX, MATCH, and EXACT) as well as modern dynamic array formulas (XLOOKUP and FILTER).
To bypass Excel's default case-insensitivity, we must use the EXACT function. The syntax for this function is straightforward:
=EXACT(text1, text2)
The EXACT function compares two text strings and returns TRUE if they are identical (including casing) and FALSE if they are not. For example:
=EXACT("Excel", "excel") returns FALSE=EXACT("Excel", "Excel") returns TRUEBy forcing EXACT to compare a lookup value against an entire column (array) of data, we can generate an array of TRUE and FALSE values. We can then search this array for the TRUE value to identify the exact row index of our match.
For decades, the combination of INDEX and MATCH has been the gold standard for complex lookups. By nesting EXACT inside this combination, we can create a powerful case-sensitive lookup engine.
=INDEX(return_range, MATCH(TRUE, EXACT(lookup_value, lookup_range), 0))
To understand why this formula works on unsorted data, let us break it down from the inside out:
EXACT(lookup_value, lookup_range): This compares your specific lookup value against every cell in the lookup_range. Because it is comparing one value against multiple cells, it outputs an array of booleans. For example, if your range has five cells and the third cell is an exact match, it outputs: {FALSE; FALSE; TRUE; FALSE; FALSE}.MATCH(TRUE, ..., 0): The MATCH function is configured to look for the value TRUE inside the boolean array generated by the EXACT step. The third argument (0) specifies an exact match. This tells Excel to locate the exact position of the first TRUE. In our example array, it will return 3. Because we specified 0 for an exact match, the data does not need to be sorted.INDEX(return_range, position): Finally, the INDEX function takes the row position (e.g., 3) and retrieves the corresponding value from the return_range.{ }, signaling to Excel that it is an array formula. In Microsoft 365 and Excel 2021, you can simply press Enter.
If you are using Microsoft 365 or Excel 2021, you have access to XLOOKUP. This function is cleaner, safer, and does not require the old "Ctrl + Shift + Enter" key combination. We can combine XLOOKUP with EXACT to achieve the same case-sensitive results with a more readable formula.
=XLOOKUP(TRUE, EXACT(lookup_value, lookup_range), return_range, "Not Found", 0)
XLOOKUP natively supports array operations, so you don't have to worry about Ctrl + Shift + Enter."Not Found") allows you to specify a fallback value if no case-sensitive match is found, eliminating the need to wrap your formula in an extra IFERROR function.0) ensures an exact match on our boolean array, maintaining stability on unsorted data lists.Let us look at a practical dataset containing unsorted, case-sensitive product IDs and their respective store locations. We want to find the exact location of the item code "co-09". Note that our data also contains "CO-09" and "Co-09".
| Row | A (Product ID) | B (Storage Location) |
|---|---|---|
| 2 | CO-09 | Aisle 4, Shelf A |
| 3 | Co-09 | Aisle 1, Shelf B |
| 4 | co-09 | Aisle 9, Shelf C |
| 5 | CO-09-A | Aisle 2, Shelf D |
If we used a standard, case-insensitive VLOOKUP("co-09", A2:B5, 2, FALSE), Excel would match the first instance it found: "CO-09" in Row 2, returning "Aisle 4, Shelf A". This is incorrect.
To find the correct location for lowercase "co-09", we write our case-sensitive formula. Let's assume our lookup value "co-09" is typed into cell D2.
=INDEX(B2:B5, MATCH(TRUE, EXACT(D2, A2:A5), 0))
This formula resolves as follows:
EXACT("co-09", {"CO-09"; "Co-09"; "co-09"; "CO-09-A"}) yields {FALSE; FALSE; TRUE; FALSE}.MATCH(TRUE, {FALSE; FALSE; TRUE; FALSE}, 0) finds TRUE at position 3.INDEX(B2:B5, 3) returns the value from the 3rd row of the range: "Aisle 9, Shelf C".=XLOOKUP(TRUE, EXACT(D2, A2:A5), B2:B5, "Missing")
This processes the exact same array logic and cleanly outputs "Aisle 9, Shelf C". If "co-09" was missing entirely, it would display "Missing".
In highly unsorted or messy datasets, you might have duplicate entries with the exact same casing, and you may want to return all matching values instead of just the first one. INDEX/MATCH and XLOOKUP are hardcoded to stop at the first match they find.
To extract *all* matching records, we can use the dynamic FILTER function combined with EXACT:
=FILTER(return_range, EXACT(lookup_value, lookup_range), "No Matches Found")
If there are two instances of "co-09" in your unsorted list, this formula will automatically spill down and display the returned values for both matches, creating an incredibly dynamic reporting dashboard.
When working with large, unsorted datasets, keep the following considerations in mind:
A:A instead of A2:A10000) forces Excel to run millions of text comparisons. This can cause Excel to freeze or lag. Always limit your ranges to the actual data boundaries.EXACT function takes spaces seriously. If your lookup cell contains "co-09" and your dataset has "co-09 " (with a trailing space), EXACT will return FALSE. Clean your ranges using the TRIM function if you suspect formatting issues:
=XLOOKUP(TRUE, EXACT(TRIM(D2), TRIM(A2:A5)), B2:B5)
#N/A error. Wrap older formula models in IFERROR(..., "No Match") to keep your spreadsheets looking professional and clean.While Excel's default behavior is to treat uppercase and lowercase letters as identical, bypassing this limitation is straightforward once you know how to use the EXACT function. By pairing EXACT with classic INDEX/MATCH or modern XLOOKUP, you can safely search unsorted data and return precise, case-sensitive results.
Disclaimer:
The documents and templates provided on this page are for informational and illustrative purposes only. They do not constitute professional, legal, or financial advice, and should not be relied upon as such. Because individual circumstances and regulatory requirements vary, these materials may not be suitable for your specific needs. We recommend consulting with a qualified professional before adapting or using any of these examples for official or commercial purposes.