Skip to content

FILTER and REGEXMATCH keep partial cells when the pattern has no ^ and $

Updated

REGEXMATCH succeeds when the pattern matches anywhere in the cell. FILTER then keeps every TRUE row. The pattern A12 keeps A12, and it also keeps A12-X, XA12, and A123. There is no #N/A. The list looks successful and it is too wide. ^ and $ mean the pattern has to be the whole cell.

A dot that matches any character, and a bare (, are FILTER + REGEXMATCH. This page does not rebuild that sku. Keep the Google Sheets UI in English. Sheet Error is an independent formula-error library, not a Google product.

  1. Open a blank spreadsheet. In A1 type sku, B1 bay. A2 A12, B2 exact. A3 A12-X, B3 suffix. A4 XA12, B4 prefix. A5 A123, B5 longer. In A6 type A12 followed by a space, B6 space. Five skus. Only A2 is the characters A, 1, 2 and nothing else.

Unanchored. Leave D2:E6 empty. In D1 type part. In D2 enter =FILTER(A2:B6,REGEXMATCH(A2:A6,"A12")). The spill includes exact, suffix, prefix, longer, and space. Each of those cells contains A12 somewhere. No error triangle. You asked for a code and received every row the pattern could touch. Leave D2 as that wide spill.

D2 selected. Formula bar shows =FILTER(A2:B6,REGEXMATCH(A2:A6,"A12")). The spill includes A12, A12-X, XA12, A123, and A12 with a trailing space. No error triangle.

Whole cell. In D8 type whole. In D9 enter =FILTER(A2:B6,REGEXMATCH(A2:A6,"^A12$")). The spill is one row: A12 / exact. A12-X fails because of the suffix. XA12 fails because of the prefix. A123 fails because of the extra digit. The trailing space in A6 fails because a space is a character. D9 is the control.

The same tests without FILTER. In G2 enter =REGEXMATCH(A3,"A12"). G2 is TRUE. In G3 enter =REGEXMATCH(A3,"^A12$"). G3 is FALSE. A3 is A12-X. The pattern did not change its letters. The anchors did. Leave G2 as TRUE and G3 as FALSE.

A real miss. In G5 enter =FILTER(A2:B6,REGEXMATCH(A2:A6,"^Z9$")). #N/A, because nothing is the whole cell Z9. That empty result is FILTER no match. D2 is not that. D2 returned rows.

Leave D2 wide. Leave D9 as the single exact row.

  • REGEXMATCH is a search, not an equality test. Without ^ and $, a hit in the middle of the cell is enough. D2 is that rule, applied to five skus that all contain those three characters.
  • ^ anchors the start. $ anchors the end. Both are required for “the cell is exactly this.” ^A12 still matches A12-X, because the start is A12 and the end is free. A12$ still matches XA12.
  • A trailing space is not trimmed by the anchors. A6 fails ^A12$ on purpose. TRIM belongs in the pattern’s input when the sheet has padded codes: REGEXMATCH(TRIM(A2:A6),"^A12$") needs ARRAYFORMULA around TRIM if you pass the whole column. Cleaning the cells is the durable fix.
  • Case is still exact. ^a12$ does not match A12. See REGEXMATCH (?i).
  • QUERY matches tests the whole cell already. People arriving from that clause expect REGEXMATCH to do the same. It does not, until you add the anchors. See CONTAINS vs MATCHES.

This is not SEARCH inside FILTER, which errors with #VALUE! on a row that lacks the text. See FILTER contains. D2 did not error. It kept too many rows.

The metacharacter . is a different extra match. N12.4 matching N12X4 is FILTER + REGEXMATCH. Escaping a dot does not stop A12 from matching A123.

Leave D2 as the wide spill.

Anchor the code. Keep D9. When the pattern is built from a cell, escape regex characters and then wrap the anchors. In G7 enter =FILTER(A2:B6,REGEXMATCH(A2:A6,"^"&"A12"&"$")). The spill matches D9: one row, A12 / exact.

D9 selected. Formula bar shows =FILTER(A2:B6,REGEXMATCH(A2:A6,"^A12$")). The spill is A12 and exact. D2 still lists A12-X, XA12, A123, and the spaced A12.

Equality when the code is literal. In G9 enter =FILTER(A2:B6,A2:A6="A12"). That also returns only A2. Use it when you do not need a pattern. REGEXMATCH is for patterns. Anchors are how a pattern becomes a whole cell.

Do not wrap D2 in IFNA. It is not #N/A. The extra rows are matches.

If FILTER returns A12-X for the pattern A12, the pattern is unanchored. Add ^ and $. If the pattern contains a dot or an open parenthesis, use the metacharacter page. If the spill is #N/A and the tooltip says no matches, the code really is absent.