Regex in Search Console: i filtri che servono davvero

Regex in Search Console: i filtri che servono davvero

Il filtro regex del report Prestazioni di Search Console permette di isolare in un colpo solo gruppi di query o di pagine che nessun filtro "contiene" o "corrispondenza esatta" riesce a catturare insieme: le domande, le varianti del brand, le query lunghe, le sezioni di un sito. La sintassi però non è quella dei tutorial generici su Python o PHP: Search Console usa RE2, il motore di Google, che manca di alcune funzioni molto comuni nei regex "classici" e che di default non ancora il confronto all'inizio o alla fine della stringa. Questo articolo raccoglie i pattern che servono davvero in un'analisi quotidiana e segna con precisione dove RE2 costringe a cambiare approccio.

Il filtro si applica a due dimensioni distinte, Query e Pagine, e ognuna ha le sue insidie: una query arriva già normalizzata da Google, una pagina è un URL vero con maiuscole, punti e slash che vanno gestiti come tali. I paragrafi seguenti trattano entrambe, con pattern pronti da adattare e la logica dietro ciascuno, non solo la stringa da copiare.

Come impostare un filtro regex nel report Prestazioni

Nel report Prestazioni, il pulsante "+ Nuovo" apre due famiglie di filtro, Query e Pagine. Entrambe offrono, oltre a "Contiene" e "Corrispondenza esatta", due opzioni basate su regex: una che mantiene le righe che corrispondono al pattern e una che mantiene quelle che non vi corrispondono. Il pattern si scrive nudo, senza slash iniziali o finali e senza alcun prefisso del tipo "regex:".

Due comportamenti predefiniti vanno tenuti a mente perché non sono intuitivi e cambiano l'esito di ogni filtro costruito sopra di essi. Il confronto sulle query è insensibile alle maiuscole, il che raramente si nota perché le query in Search Console arrivano già normalizzate in minuscolo; il confronto sulle pagine invece è sensibile al maiuscolo, perché lavora sull'URL reale così come è stato scansionato. Inoltre il pattern non è ancorato per impostazione predefinita: scrivere "blog" fa corrispondere qualunque query o URL che contenga quella sequenza di caratteri in una posizione qualsiasi, non solo all'inizio o come parola intera. Per un confronto esatto occorre aggiungere manualmente il circonflesso e il simbolo del dollaro.

  • "Personalizzato (regex)": mantiene le righe che corrispondono al pattern.
  • "Personalizzato (non corrisponde alla regex)": mantiene le righe che non corrispondono.
  • Nessun delimitatore e nessun prefisso: si scrive solo il pattern, così com'è.
  • Query confrontate senza distinzione di maiuscole; Pagine confrontate sull'URL reale, quindi sensibili al maiuscolo.

Isolare le query che sono domande

Le query formulate come domanda segnalano quasi sempre intento informativo puro, utile da separare dal resto per capire quanta parte del traffico arriva da chi sta ancora raccogliendo informazioni piuttosto che da chi è pronto a decidere. Un unico pattern con alternanza tra le parole interrogative italiane, ancorato all'inizio e chiuso da un confine di parola, sostituisce una decina di filtri "contiene" separati:

^(chi|cosa|come|quando|dove|perch[eé]|qual[ei]|quant[oi])(\s|$)

Il gruppo finale (\s|$) fa da confine di parola dopo l'alternanza (in RE2 \b considera solo caratteri ASCII e non funzionerebbe dopo una lettera accentata come in "perché"), ed è quello che rende il pattern utile e non un semplice controllo di prefisso: senza di esso, "come" corrisponderebbe anche a query come "comesto" o "comercio", perché il motore si limiterebbe a verificare che quei caratteri appaiano in sequenza all'inizio della stringa. Con il confine di parola, il carattere successivo alla sequenza deve essere uno spazio o la fine della query, quindi "come si fa" viene incluso mentre "comercio online" viene escluso correttamente.

La classe di caratteri [eé] e [ei] serve a coprire le varianti con e senza accento che le persone digitano quando la tastiera non facilita i caratteri accentati: "perche" e "perché" finiscono entrambe nel segmento, così come "quali" e "quale". Chi vuole isolare solo le domande "quanto costa" o "quanto costano", tipiche di query commerciali con intento informativo misto, può restringere il pattern a "^quant[oi]\b" e leggere il segmento da solo, separandolo dalle domande più genericamente informative.

Separare il traffico brand da quello non brand

Chi ha un nome di marca da monitorare conosce il problema: le varianti sono tante, tra errori di battitura, spaziature diverse e la marca incorporata in una query più lunga insieme a un termine generico, come "nomemarca recensioni" o "nome marca prezzo". Impilare una serie di filtri "contiene" per ogni variante è lento e si dimentica sempre qualche combinazione. Un pattern con alternanza cattura tutte le varianti attese in un solo filtro; per una marca di fantasia "Lumis" potrebbe essere:

\blum[i1]s\b|\blu\s?mis\b

La prima parte cattura "lumis" e la variante con il numero "1" al posto della "i", un errore di digitazione comune su tastiere mobili; la seconda cattura la marca scritta con o senza spazio interno. Il pattern va adattato caso per caso guardando l'elenco reale delle query che già contengono la marca, disponibile nel report non filtrato, e aggiungendo le varianti che effettivamente compaiono, non quelle immaginate a tavolino.

Per ottenere il traffico non brand, la tentazione di chi ha già scritto regex altrove è costruire un pattern negativo con un lookahead, del tipo "^(?!.*lumis).*$", per escludere la marca in un solo colpo. In RE2 questa sintassi non esiste: lookahead e lookbehind non fanno parte della grammatica supportata, e il filtro con quella stringa non produce il risultato atteso. La soluzione non è scrivere un pattern più complicato, ma usare il secondo menu che Search Console offre di fianco al primo: si scrive il pattern della marca esattamente come per isolarla, poi si seleziona "non corrisponde alla regex" invece di "corrisponde alla regex". L'esclusione è un'opzione dell'interfaccia, non una proprietà che deve stare dentro il pattern.

Trovare le query long-tail per lunghezza, non per parole chiave

Una query long-tail si definisce meglio dalla sua struttura che dal suo argomento: più parole, spesso una domanda implicita, quasi sempre meno traffico per singola query ma un volume aggregato che nella coda lunga può essere rilevante. Cercare la coda lunga elencando argomenti è un lavoro senza fine; cercarla per struttura richiede un solo pattern.

^(?:\S+\s+){4,}\S+$

Il gruppo non catturante "(?:\S+\s+)" descrive una sequenza di caratteri non spazio seguita da uno spazio, cioè una parola con lo spazio che la segue; la quantità "{4,}" chiede che questo blocco si ripeta almeno quattro volte, e l'ultima parte "\S+$" chiede un'ultima parola fino alla fine della stringa. Il risultato sono le query di cinque parole o più. Vale la pena notare che qui la ripetizione riguarda un gruppo, non un riferimento al testo già trovato: RE2 permette di ripetere una struttura quante volte serve, quello che non permette è richiamare indietro cosa quella struttura ha effettivamente catturato la prima volta.

Per il campo Pagine, dove l'unità di interesse è più spesso lo slug che le singole parole, la lunghezza in caratteri è la misura più diretta:

^.{60,}$

Le pagine con uno slug sopra una certa soglia di caratteri meritano un controllo perché tendono a corrispondere a titoli lunghi, categorie annidate in profondità o parametri finiti per errore nel path. Una volta isolato il segmento per struttura, che sia per parole nelle query o per caratteri nelle pagine, il confronto tra le metriche aggregate di quel segmento e quelle del resto del traffico diventa immediato, senza dover etichettare riga per riga.

Segmentare le pagine per sezione del sito

Il filtro sulle Pagine lavora sull'URL completo così come Google lo ha scansionato, protocollo e dominio incluso, non solo sul percorso. Questo significa che ogni punto nel dominio va sempre trattato come carattere letterale con una barra inversa davanti, perché il punto non escapato in un regex significa "un carattere qualsiasi" e amplia il filtro in modo silenzioso.

^https://tuosito\.it/blog/

Per isolare una sola lingua su un sito che serve più lingue da sottocartelle, ancorare subito dopo il dominio funziona bene:

^https://tuosito\.it/it/

Per isolare le pagine di recensione annidate dentro una struttura a categorie, indipendentemente dal nome del prodotto intermedio:

/prodotti/[^/]+/recensioni/?$

La classe "[^/]+" chiede uno o più caratteri diversi dalla barra, cioè esattamente un segmento di percorso, qualunque sia il suo contenuto; lo slash finale reso opzionale con "/?" copre sia la versione con barra finale che quella senza, una differenza che molti CMS non gestiscono in modo coerente.

  • ^https://tuosito\.it/[^/]+/[^/]+/[^/]+/?$ isola le pagine a esattamente tre livelli di profondità, utile per trovare categorie annidate che meritano una verifica.
  • \.pdf($|\?) isola i documenti PDF indicizzati, includendo anche quelli con parametri dopo l'estensione.
  • \? da solo isola qualunque URL con una stringa di query, spesso segno di navigazione a faccette finita in indice per errore.

I limiti della sintassi RE2: cosa non si può fare

RE2 è il motore che Google usa internamente per motivi di prestazioni e di sicurezza, e la sua caratteristica distintiva è che ogni pattern viene eseguito in un tempo prevedibile, a costo di rinunciare a qualche funzione che chi scrive regex altrove considera scontata.

Quello che invece resta pienamente disponibile, e che coprirà la grande maggioranza dei filtri utili in un'analisi SEO, è tutto ciò che non richiede di guardare indietro nel testo: alternanza con la barra verticale, classi di caratteri, quantificatori come più, asterisco e le parentesi graffe, confini di parola, ancore di inizio e fine stringa, gruppi non catturanti. La parte che manca è quella delle funzioni avanzate tipiche di Perl, non l'ossatura di base dei regex.

  • Lookahead e lookbehind, cioè i costrutti "(?=...)", "(?!...)", "(?<=...)" e "(?<!...)", non esistono in RE2. Non si può quindi scrivere in un solo pattern "contiene X ma non contiene Y"; la soluzione, come visto per il brand, è usare il secondo filtro dell'interfaccia dedicato a "non corrisponde alla regex" invece di negare dentro il pattern stesso.
  • I backreference, cioè richiami come "\1" o "\2" a una parte già catturata dallo stesso pattern, non sono supportati. Non è quindi possibile scrivere un pattern generico che rilevi la stessa parola ripetuta due volte in una query; se serve individuare quel caso, va enumerato esplicitamente per le parole che interessano.
  • Gruppi atomici e quantificatori possessivi, costrutti pensati per controllare il backtracking in altri motori, non hanno motivo di esistere in RE2 perché RE2 non usa il backtracking: la garanzia di tempo prevedibile viene proprio da un algoritmo diverso, non da un'ottimizzazione dello stesso algoritmo.

Errori comuni che falsano il filtro

Dimenticare il confine di parola è l'errore più frequente: un pattern come "moda" senza "\b" davanti e dietro intercetta anche query come "comoda" o "modalità", perché il confronto di default è per sottostringa e non per parola intera. Aggiungere "\bmoda\b" risolve il problema nella maggior parte dei casi, salvo quando la query contiene punteggiatura attaccata alla parola, un caso raro ma non impossibile nei dati reali.

Il punto non escapato nel filtro sulle Pagine è il secondo errore più comune: un dominio scritto come "tuosito.it" senza barra inversa davanti al punto corrisponde anche a "tuositoXit" per qualunque carattere X, un rischio concreto quando il pattern viene poi riusato per un dominio diverso senza correggere l'escape.

Dare per scontato che le Pagine si comportino come le Query in fatto di maiuscole è un terzo errore: "/Blog/" e "/blog/" sono pattern diversi agli occhi del filtro, e un CMS che genera URL con maiuscole incoerenti tra sezioni farà sfuggire righe che sembravano già coperte.

Copiare un pattern scritto per un altro strumento, magari con lookahead o backreference già dentro, e aspettarsi che produca lo stesso risultato in Search Console porta quasi sempre a un filtro che non seleziona nulla o seleziona tutto, senza un messaggio di errore chiaro che lo segnali.

Infine, sperare che un pattern sulla sola query riveli l'intento di acquisto è un errore di aspettativa più che di sintassi: il testo della query raramente lo dice da solo, e il pattern regex rende preciso e ripetibile un segmento, ma la definizione di quel segmento, cosa considerare "vicino all'acquisto" o "informativo", resta una decisione da prendere guardando i dati, non qualcosa che il motore regex può indovinare per conto proprio.

Domande frequenti

I filtri regex di Search Console sono sensibili alle maiuscole?

Sul campo Query no, perché Google normalizza già le query in minuscolo prima di mostrarle nel report. Sul campo Pagine sì, perché il filtro opera sull'URL reale così come è stato scansionato, quindi "/Blog/" e "/blog/" sono trattati come pattern diversi.

Perché il mio pattern con "(?!...)" non funziona?

Perché Search Console usa il motore RE2, che non supporta i lookahead né i lookbehind. Al posto di negare qualcosa dentro il pattern, va scritto il pattern positivo e selezionata l'opzione "non corrisponde alla regex" invece di "corrisponde alla regex".

Devo sempre ancorare il pattern con ^ e $?

Solo se vuoi un confronto esatto sull'intera stringa. Di default il filtro cerca il pattern in una posizione qualsiasi della query o dell'URL, quindi un pattern non ancorato si comporta come una ricerca di sottostringa e può includere corrispondenze indesiderate.

Posso usare la stessa regex sia per Query che per Pagine?

Tecnicamente sì, ma raramente ha senso: le query sono testo normalizzato senza protocollo né dominio, mentre le pagine sono URL completi con maiuscole reali e punti da escapare. Un pattern pensato per l'uno va quasi sempre riadattato per l'altro.

Tutti gli articoli