O pacote regexp oferece suporte para expressões regulares em Go.
A sintaxe das expressões regulares aceites é a mesma sintaxe geral usada por Perl, Python e outras linguagens.
Tanto os padrões de pesquisa como os textos de entrada são interpretados como UTF-8.
Quando usamos backticks (`) para criar strings, as barras invertidas (\) não têm nenhum significado especial e não marcam o início de carateres especiais como tabulações \t ou novas linhas \n:
"\t\n" // regular string literal with 2 characters: a tab and a newline
`\t\n`// raw string literal with 4 characters: two backslashes, a 't', and an 'n'
Por isso, é preferível usar backticks para criar expressões regulares, porque assim não precisamos de escapar as barras invertidas:
"\\" // string with a single backslash
`\\` // string with 2 backslashes
RegExp
Para usar uma expressão regular, temos primeiro de compilar o padrão.
Compilar, aqui, significa transformar a string com o padrão da expressão regular numa representação interna mais fácil de trabalhar.
Só precisamos de compilar cada padrão uma vez; depois disso, podemos usar a versão compilada da expressão regular muitas vezes.
O tipo regexp.Regexp representa uma expressão regular compilada.
Podemos compilar um padrão (uma string) num regexp.Regexp com a função regexp.Compile.
Esta função devolve nil e um erro se a compilação falhar:
re, err := regexp.Compile(`(a|b)+`)
fmt.Println(re, err) // => (a|b)+ <nil>
re, err = regexp.Compile(`a|b)+`)
fmt.Println(re, err) // => <nil> error parsing regexp: unexpected ): `a|b)+`
A função MustCompile é uma alternativa cómoda a Compile:
re = regexp.MustCompile(`[a-z]+\d*`)
Com esta função, não é preciso tratar nenhum erro.
MustCompile só deve ser usado quando temos a certeza de que o padrão compila; caso contrário, o programa vai entrar em pânico.
Existem 16 métodos de Regexp que aplicam uma expressão regular e identificam o texto correspondido.
Os seus nomes correspondem a esta expressão regular:
Find(All)?(String)?(Submatch)?(Index)?
All estiver presente, a rotina corresponde a correspondências sucessivas e não sobrepostas de toda a expressão.String estiver presente, o argumento é uma string; caso contrário, é um slice de bytes; os valores devolvidos são ajustados em conformidade.Submatch estiver presente, o valor devolvido é um slice que identifica as subcorrespondências sucessivas da expressão.Index estiver presente, as correspondências e as subcorrespondências são identificadas por pares de índices de bytes dentro da string de entrada.Existem também métodos para:
No total, o pacote regexp define mais de 40 funções e métodos.
Abaixo vamos demonstrar a utilização de alguns métodos.
Consulta a documentação da API para obteres os detalhes destas e de outras funções.
MatchString
O método MatchString indica se uma string contém alguma correspondência de uma expressão regular.
re = regexp.MustCompile(`[a-z]+\d*`)
b = re.MatchString("[a12]") // => true
b = re.MatchString("12abc34(ef)") // => true
b = re.MatchString(" abc!") // => true
b = re.MatchString("123 456") // => false
FindString
O método FindString devolve uma string com o texto da correspondência mais à esquerda da expressão regular.
re = regexp.MustCompile(`[a-z]+\d*`)
s = re.FindString("[a12]") // => "a12"
s = re.FindString("12abc34(ef)") // => "abc34"
s = re.FindString(" abc!") // => "abc"
s = re.FindString("123 456") // => ""
FindStringSubmatch
O método FindStringSubmatch devolve um slice de strings com o texto da correspondência mais à esquerda da expressão regular e as correspondências, caso existam, das suas subexpressões.
Isto pode ser usado para identificar as strings que correspondem a grupos de captura.
Um valor devolvido nil indica que não houve correspondência.
re = regexp.MustCompile(`[a-z]+(\d*)`)
sl = re.FindStringSubmatch("[a12]") // => []string{"a12","12"}
sl = re.FindStringSubmatch("12abc34(ef)") // => []string{"abc34","34"}
sl = re.FindStringSubmatch(" abc!") // => []string{"abc",""}
sl = re.FindStringSubmatch("123 456") // => <nil>
ReplaceAllString
O método re.ReplaceAllString(src,repl) devolve uma cópia de src, substituindo as correspondências da expressão regular re pela string de substituição repl.
re = regexp.MustCompile(`[a-z]+\d*`)
s = re.ReplaceAllString("[a12]", "X") // => "[X]"
s = re.ReplaceAllString("12abc34(ef)", "X") // => "12X(X)"
s = re.ReplaceAllString(" abc!", "X") // => " X!"
s = re.ReplaceAllString("123 456", "X") // => "123 456"
Split
O método re.Split(s,n) divide um texto s em substrings separadas pela expressão e devolve um slice das substrings entre essas correspondências da expressão.
O valor n determina o número máximo de substrings a devolver.
Se n<0, o método devolve todas as substrings.
re = regexp.MustCompile(`[a-z]+\d*`)
sl = re.Split("[a12]", -1) // => []string{"[","]"}
sl = re.Split("12abc34(ef)", 2) // => []string{"12","(ef)"}
sl = re.Split(" abc!", -1) // => []string{" ","!"}
sl = re.Split("123 456", -1) // => []string{"123 456"}
A implementação de regexp fornecida por este pacote garante que corre em tempo linear em relação ao tamanho da entrada.
O pacote regexp implementa expressões regulares RE2 (exceto \C).
A sintaxe é em grande parte compatível com PCRE ("Perl Compatible Regular Expression"), mas há algumas diferenças.
Consulta a secção "Caveat section" deste artigo para mais detalhes.