MiServe DevTools

I tuoi adesivi

Fissa qui gli strumenti. Restano salvati in questo browser.

Tester di regex per JavaScript e Go (RE2)

Prova un'espressione regolare sul tuo testo con il motore di JavaScript o con il motore RE2 di Go, e guarda ogni corrispondenza, gruppo di cattura e sostituzione.

Flag

Corrispondenze nel testo

Riepilogo della sintassi dei due motori
TokenSignificatoJavaScriptGo (RE2)
. Qualsiasi carattere tranne un a capo. Con il flag s include anche gli a capo. Sì Sì
\d \w \s Una cifra, un carattere di parola, uno spazio bianco. Le maiuscole \D, \W e \S indicano il contrario. Sì Sì
[abc] [^abc] [a-z] Un carattere di un insieme, un carattere che non è nell'insieme, un carattere in un intervallo. Sì Sì
^ $ Inizio e fine del testo. Con il flag m, inizio e fine di ogni riga. Sì Sì
\b \B Un confine di parola, e una posizione che non è un confine di parola. Sì Sì
* + ? {2,5} Zero o più volte, una o più volte, zero o una volta, da 2 a 5 volte. Ognuno prende quanto più può. Sì Sì
*? +? ?? {2,5}? Gli stessi quantificatori, che prendono quanto meno possono. Sì Sì
(…) (?:…) Un gruppo di cattura, e un gruppo che raggruppa soltanto. Sì Sì
(?<name>…) Un gruppo di cattura con nome. Go accetta questa forma dalla versione 1.22, e (?P<name>…) in tutte le versioni. Sì Sì
a|b a oppure b. Sì Sì
\p{L} \p{Lu} Una proprietà Unicode: qualsiasi lettera, qualsiasi lettera maiuscola. In JavaScript serve il flag u. Sì Sì
(?i) (?s) (?m) Flag scritti dentro il pattern. In JavaScript i flag si impostano fuori. No Sì
\A \z Inizio e fine dell'intero testo, a prescindere dal flag m. No Sì
[[:alpha:]] Una classe di caratteri POSIX dentro un insieme. No Sì
(?=…) (?!…) Lookahead: ciò che segue deve corrispondere, o non deve corrispondere, senza essere consumato. Sì No
(?<=…) (?<!…) Lookbehind: ciò che precede deve corrispondere, o non deve corrispondere. Sì No
\1 \k<name> Backreference: lo stesso testo trovato da un gruppo precedente. Sì No

Funziona nel tuo browser con WebAssembly. Nulla di ciò che incolli viene caricato.

Informazioni su questo strumento

Due motori di due famiglie

I motori di espressioni regolari si dividono in due famiglie. I motori a backtracking, come PCRE e i motori predefiniti di JavaScript, Python, Java e .NET, provano un percorso nel pattern e tornano indietro quando fallisce. Questo approccio rende possibili lookahead, lookbehind e backreference. I motori ad automa, come RE2 e il package regexp di Go, seguono tutti i percorsi possibili insieme, quindi il loro tempo di esecuzione cresce in modo lineare con la lunghezza del testo. Il prezzo da pagare è che lookaround e backreference non sono disponibili.

Il motore JavaScript qui è il RegExp del tuo browser. Il motore Go è il package standard regexp di Go compilato in WebAssembly, quindi il codice che esegue qui il tuo pattern è lo stesso che lo esegue in un programma Go. Go accetta la sintassi di RE2.

Come leggere i risultati

Ogni corrispondenza è contornata ed evidenziata nel testo, in due colori alternati, così da distinguere le corrispondenze che si toccano. Una corrispondenza vuota, come quella che x* trova tra due lettere, è disegnata come una barra sottile. La tabella elenca inizio e fine di ogni corrispondenza e il testo di ogni gruppo di cattura. Un gruppo che non ha preso parte a una corrispondenza è segnato come «non trovato», che è diverso da un gruppo che ha trovato una stringa vuota.

Le posizioni contano le code unit UTF-16 a partire da zero, e la fine è esclusa: sono i numeri che passeresti a String.prototype.slice in JavaScript. Go invece riporta gli offset in byte nel testo UTF-8; lo strumento li converte, così entrambi i motori mostrano gli stessi numeri.

In JavaScript, un pattern senza il flag g trova solo la prima corrispondenza e sostituisce solo la prima. Il motore Go riporta sempre tutte le corrispondenze, come fanno FindAllStringSubmatchIndex e ReplaceAllString.

Catastrophic backtracking

Un motore a backtracking può richiedere un tempo esponenziale quando i quantificatori sono annidati o si sovrappongono. Il caso classico è (a+)+$ applicato a una lunga sequenza di a seguita da un altro carattere: prima di arrendersi, il motore prova ogni modo di dividere la sequenza tra il quantificatore interno e quello esterno. Su un server questo è un rischio di denial of service noto come ReDoS.

Questo strumento esegue i pattern JavaScript in un worker in background e lo ferma dopo 1,5 secondi, così la pagina resta reattiva e ti dice cosa è successo. Provare lo stesso pattern con il motore Go è un modo rapido per capire se la lentezza dipende dal backtracking, perché Go garantisce un tempo di esecuzione lineare rispetto alla lunghezza del testo.

Domande

Perché il mio pattern funziona in JavaScript ma non in Go?

Una causa frequente è un lookahead, un lookbehind o una backreference, che RE2 esclude per poter garantire un tempo di esecuzione lineare. Un'altra causa frequente sono i flag: in Go non esistono flag fuori dal pattern, quindi la ricerca senza distinzione tra maiuscole e minuscole si scrive con (?i) all'inizio.

In cosa differiscono le stringhe di sostituzione tra JavaScript e Go?

Entrambi usano $1 per il primo gruppo. Un gruppo con nome è $<name> in JavaScript e ${name} in Go. In Go, $1x indica un gruppo chiamato 1x, quindi scrivi ${1}x quando dopo il riferimento segue una lettera, una cifra o un underscore.

Posso provare qui pattern PCRE, Python o Java?

Su questa pagina girano solo i motori di JavaScript e di Go. La sintassi di tutti i giorni è comune ai vari dialetti, quindi per i pattern semplici il motore JavaScript è una buona approssimazione, ma funzionalità come quantificatori possessivi, gruppi atomici e ricorsione non sono disponibili in nessuno dei due motori.

Il testo che provo viene inviato a un server?

No. Entrambi i motori girano nel tuo browser: JavaScript in un worker in background, Go come modulo WebAssembly. Lo strumento non fa alcuna richiesta di rete con il tuo pattern o il tuo testo, e la policy di sicurezza del sito blocca le richieste verso qualsiasi altro host.

Altri strumenti in Testo