Search Console Regex Not Working? How to Test and Fix It

About 26 minutes

By now we can write pretty good regex: we can isolate brand and non-brand, pull out long queries, pick out questions, comparisons and price queries, handle messy spellings, and analyze whole sections of the site. But there's a problem more dangerous than a regex throwing an error: a regex that runs perfectly normally, returns results, and you think it's right, when in fact it's returning a different segment from the one you wanted. That's far more dangerous than an obvious error.

The first rule: a regex that runs isn't necessarily a regex that's right

You want the comparison queries, and you wrote:

(compare|versus|difference between| or )
  • compare iphone and samsung
  • iphone versus samsung
  • difference between macbook air and pro
  • iphone or samsung
  • is shipping free or not
  • is the warranty one year or two

The first four queries are great. But the last two? They contain " or ", so the regex carried out the rule correctly, but the segment itself isn't what you meant. The problem isn't that the regex is "broken"; it's that the rule we wrote is wider than the question we're trying to answer.

Two kinds of mistake
  1. 1False positive — a result showed up, but it shouldn't be in the group (like "is shipping free or not")
  2. 2False negative — a result should be in the group, but didn't show up (like "iphone vs samsung", since the pattern has no vs)
Note
The real work is balancing the two. Widen the pattern a lot and you cut false negatives, but you may add false positives, and the reverse. There's no single answer; it depends on what you're using the segment for. A first discovery starts wider; a precise numbers report needs more review.

Don't start with the big regex

Say you want a brand regex that covers smart store, smartstore, smart-store and smrt store. It's better to start with smart store, test, then smart ?store, test, then smart[- ]?store, test, then add the typo, test. Each time you know exactly which part you added, and which new results showed up because of it.

How to build it
  1. 1The simplest pattern possible
  2. 2Test
  3. 3Add one part
  4. 4Test
  5. 5Add one part
  6. 6Test

Same as we did in Python: a small piece of code, print the result, understand it, then add more.

You need test cases before you run it

Before you put a regex into Search Console, write yourself some examples: what must show up, and what must not. Now, when you run the pattern, you have an expectation; you're not looking at the results and saying "looks good". These are like very simple unit tests for regex.

Watch out
Don't change 5 things at once. If a pattern has a problem and you add a new word, a new group, an anchor, a character class and an optional space all together, and then the result comes out right, do you know what fixed it? No. When debugging, change one thing, test, then the next.

A very important debugging question

Every time extra results show up, ask: how did the regex match this part? For example, product showed up in best-product-photography because the text is inside the URL. Search Console does a partial match by default, so the regex can match any part of the text unless you use ^ or $. When you ask "which part matched?", you reach the problem faster.

Another common problem: an anchor in the wrong place. Say you want queries that start with "how", but you wrote how$ by mistake:

how$
  • how to choose a laptop
  • laptop how

You're saying "queries that end with how", not "start with how". The regex can run and return very few results, and you think people don't search with "how", while the problem is the pattern. Read the regex out logically every time: ^how means "the start of the text, then how". how$ means "how, then the end of the text".

The most important question when you take a ready-made regex

You might take a pattern from an article, Stack Overflow, ChatGPT or a colleague. Don't only ask "does it work?". Ask "which regex engine was it made for?", because not every regex on the internet is the same regex Search Console understands. Search Console uses RE2. You don't need the programming details; what matters is that there are several regex engines, and some features that work in PCRE or Perl aren't supported in RE2.

An important example: lookahead, lookbehind and backreferences

You might see something like this online, and it doesn't matter now if you understand the whole pattern. What matters is knowing that the part (?=...) is called a positive lookahead, and RE2 doesn't support it:

iphone(?=.*price)

The negative lookahead (?!...) isn't supported either:

^(?!.*repair).*iphone.*

And if you find a lookbehind, (?<=...) or (?<!...), those aren't supported in RE2 either. Same goes for backreferences like \1.

Watch out
Do we need them in this course? Probably not. But if ChatGPT or a regex site gives you a pattern with one of these in it, don't assume it will work in Search Console, even if your browser (like the browser running the examples in this lesson) understands it and it works, because that's a completely different engine from RE2.

For every symbol, and whether it works in Search Console or only in Python, keep the regex cheat sheet open.

An important point about using AI

If you tell an AI model "make me a regex for queries with iphone but not repair", the model might give you a pattern with a negative lookahead. The fix isn't to say "regex is useless"; it's to know the limits of the environment you're working in. It's better to be clear from the start:

The rule
Write a regex compatible with Google RE2 for use in Search Console, avoid lookahead, lookbehind and backreferences, explain every part, and give me 5 cases that should match and 5 that should not. Even if the model explains the pattern well, it may have misunderstood your goal or assumed variations that don't exist. AI helps you build regex; it isn't a replacement for reviewing the real data.

So how do I include A but exclude B without a lookahead? Don't try to squeeze all the logic into one clever pattern. In Search Console you can use the filters that are there: isolate iphone with one filter, and exclude repair with a separate filter, or do the analysis in stages.

The rule
If the solution needs a feature RE2 doesn't support, don't try to invent a more complex regex. Change the way you analyze it. Not every problem has to be solved in one regex: sometimes a small regex + another filter is clearer than one huge regex. And don't try to use regex to compare metrics either: want the queries with more than 1,000 impressions? Regex isn't the tool; it matches text, not numbers in a column.

A problem: an invalid regex and no results

Google explains that an invalid regex can return no matches. So if a pattern returns zero, don't immediately assume "there's no data". The pattern could be wrong, or use unsupported syntax, or be missing an escape, or have a group that isn't closed, or you could be searching for a phrasing that really isn't there. You need to tell them apart.

The first step if the result is zero: simplify the pattern
  1. 1iphone — are there results?
  2. 2(iphone|samsung) — still there?
  3. 3(iphone|samsung).*\d — still there?
  4. 4^(iphone|samsung).*\d{4}$ — now, where did the results stop?
  5. 5The problem started after adding which part? That's simple binary debugging

Same idea with a long pattern like (?-i)^https://example\.com/(blog|guides)/.*(2025|2026).*\.pdf$. Take it apart piece by piece: (?-i) case-sensitive, ^https://example\.com/ start with the domain, (blog|guides) the blog or the guides, .* anything after it, (2025|2026) the year has to appear, .* anything, \.pdf$ and it ends in PDF. If you don't need PDFs at all, remove that part; if you don't need case sensitivity, remove it. Every part of a pattern needs a reason.

Watch out
Don't write a "just in case" regex: putting .* everywhere because you saw it in examples. Search Console does a partial match by default, so if you want "price", you don't need .*price.* in most cases. Use .* when it has a real job inside a bigger pattern.

Understanding .* properly: the order of the words

iphone.*price means "iphone, and then, anywhere after it, price", in exactly that order.

Predict the result

How many of the two queries will match iphone.*price? (Think about the order.)

iphone.*price
  • iphone 17 price
  • price iphone 17

.* doesn't mean "the two words in any order"; it allows characters between two parts in the order you wrote them. If you need both directions: (iphone.*price|price.*iphone). But ask yourself: do I need that at all? Maybe the simple price segment (price|pricing|cost|how much) plus reviewing the queries for one particular page is simpler.

Another mistake: a character class isn't a group

We covered it in the messy-queries lesson, but it's one of the most common debugging mistakes. You want "price or cost", and you wrote [price|cost] by mistake:

[price|cost]
  • iphone price
  • iphone cost
  • buy iphone
  • laptop
Watch out
Notice that everything matched, even "laptop"! Because [price|cost] means "one character from: p r i c e | c o s t", and "laptop" has a p, a t and an o in it. [] picks one character, not a word. The right way is (price|cost).
(price|cost)
  • iphone price
  • iphone cost
  • buy iphone
  • laptop

Another mistake: what exactly does the ? apply to? In smart ?store, the ? applies to the space before it. But if you wrote smart store?, the ? applies to the last e: a completely different pattern. So when you see a quantifier like ?, +, * or {n}, ask: what exactly does it apply to?

A bug versus a limitation

Note
A bug: the pattern doesn't work the way you designed it, like product instead of ^https://example.com/product/ when your goal is a specific structure. A limitation: the pattern works as you designed it, but the method itself has limits, like ^\S+(\s+\S+){6,}$, which relies on spaces, so it won't split iphone-17-pro-max into separate words. That isn't a bug; it's a known design. If you understand the difference, you'll know when to fix the regex and when to change the way you analyze.
Try it yourself

You have (price|cost|how much) against: iphone price, iphone cost, how much is an iphone, iphone pricing, iphone prices. What's the false negative? Fix the pattern.

  • iphone price
  • iphone cost
  • how much is an iphone
  • iphone pricing
  • iphone prices

iphone pricing is the false negative: pricing doesn't contain price. iphone prices is fine, because prices does.

The practical test

You have: compare iphone and samsung, iphone versus samsung, difference between macbook air and pro, iphone vs samsung, is shipping free or not, is the warranty one year or two, best iphone, iphone price.

Regex challenge

A comparison segment without false positives

Build a comparison regex that covers the main comparison cases, without bringing back "is shipping free or not" or "is the warranty one year or two" as extra results.

Must match
  • · compare iphone and samsung
  • · iphone versus samsung
  • · difference between macbook air and pro
  • · iphone vs samsung
Must not match
  • · is shipping free or not
  • · is the warranty one year or two
  • · best iphone
  • · iphone price

A thinking test

After this lesson, I don't care whether you memorized "lookahead isn't supported, lookbehind isn't supported". That's important information, but it isn't the goal. The goal is that as soon as you get a new regex, you ask: do I understand every part of it? Is it RE2-compatible? What do I expect to show up? What do I expect not to show up? What are the false positives? What are the false negatives? Is the pattern wrong, or is the method itself limited? If you do that, you're no longer someone who copies regex. You can build it, test it and fix it.

Before the next lesson

We've covered almost all the tools we need in this course. The next step doesn't need many new symbols, and it's the most important one: how to bring it all together and turn regex from a filter into a full SEO analysis. We start with a question, build a segment, check it's right, read the clicks, impressions, CTR, position and the change over time, and then ask: what decision or investigation should come out of the data? That will be the last lesson before the final project.

Well done, you reached the end of the lesson.