regexp.Regexp în Go

O expresie regulată compilată: o creezi o dată cu Compile sau MustCompile și o folosești de oricâte ori (MatchString, Find…, Replace…).

Sintaxă
func Compile(expr string) (*Regexp, error)
func MustCompile(str string) *Regexp
func CompilePOSIX(expr string) (*Regexp, error)
func MustCompilePOSIX(str string) *Regexp
func (re *Regexp) MatchString(s string) bool
func (re *Regexp) String() string

Ce face regexp.Regexp

*regexp.Regexp este o expresie regulată compilată. O creezi cu regexp.Compile(expr), care returnează și o eroare dacă expresia este greșită, sau cu regexp.MustCompile(expr), care oprește programul cu panic la o expresie greșită. MustCompile se folosește de obicei pentru expresii fixe, scrise în cod, ca variabile la nivelul pachetului.

Metoda re.MatchString(s) spune dacă textul conține o potrivire și, spre deosebire de funcția regexp.MatchString, nu mai returnează eroare (expresia a fost deja compilată). re.String() returnează textul expresiei din care a fost creat obiectul.

regexp.CompilePOSIX și regexp.MustCompilePOSIX creează tot un *Regexp, dar acceptă doar sintaxa POSIX ERE (cea din egrep: fără \d, \w, (?i) sau *?; clasele se scriu [[:digit:]]) și caută potrivirea cea mai lungă care începe cel mai devreme (leftmost-longest). Varianta obișnuită alege, ca Perl, prima alternativă care se potrivește: pentru a|ab pe „ab”, Compile găsește „a”, iar CompilePOSIX găsește „ab”. Le folosești rar, de obicei când trebuie să reproduci comportamentul unor unelte POSIX.

Un *Regexp poate fi folosit în siguranță din mai multe goroutine în același timp. Metodele lui pentru căutare și înlocuire au pagini separate: FindString, FindStringSubmatch, ReplaceAllString, Split.

Parametri

Parametru Descriere
expr / str Expresia regulată, în sintaxa RE2.
s La MatchString: textul verificat.

Ce returnează

Compile: *Regexp și eroarea. MustCompile: *Regexp. MatchString: bool. String: textul expresiei.

Exemple

Exemplul 1: Expresie compilată o singură dată

package main

import (
	"fmt"
	"regexp"
)

var reEmail = regexp.MustCompile(`^[a-z0-9._-]+@[a-z0-9-]+(\.[a-z0-9-]+)+$`)

func main() {
	for _, e := range []string{"ana.pop@exemplu.ro", "ion@", "maria@scoala.edu.ro"} {
		fmt.Printf("%-20s %t\n", e, reEmail.MatchString(e))
	}
	fmt.Println("expresia:", reEmail.String())
}

Rezultat

ana.pop@exemplu.ro   true
ion@                 false
maria@scoala.edu.ro  true
expresia: ^[a-z0-9._-]+@[a-z0-9-]+(\.[a-z0-9-]+)+$

Exemplul 2: Compile pentru o expresie venită de la utilizator

O expresie scrisă de utilizator poate fi greșită; Compile returnează eroarea în loc să oprească programul.

package main

import (
	"fmt"
	"regexp"
)

func main() {
	for _, expr := range []string{`^Ia`, `[a-z`} {
		re, err := regexp.Compile(expr)
		if err != nil {
			fmt.Println("expresie invalidă:", err)
			continue
		}
		fmt.Println(re, "->", re.MatchString("Iași"))
	}
}

Rezultat

^Ia -> true
expresie invalidă: error parsing regexp: missing closing ]: `[a-z`

Exemplul 3: CompilePOSIX: potrivirea cea mai lungă

Cu aceeași expresie, varianta obișnuită se oprește la prima alternativă care merge, iar varianta POSIX alege potrivirea cea mai lungă. \d nu face parte din sintaxa POSIX, deci CompilePOSIX îl refuză.

package main

import (
	"fmt"
	"regexp"
)

func main() {
	text := "Iași-Vaslui"
	perl := regexp.MustCompile(`Iași|Iași-Vaslui`)
	posix := regexp.MustCompilePOSIX(`Iași|Iași-Vaslui`)
	fmt.Println("Compile:     ", perl.FindString(text))
	fmt.Println("CompilePOSIX:", posix.FindString(text))

	cifre := regexp.MustCompilePOSIX(`[[:digit:]]+`)
	fmt.Println(cifre.FindString("cod poștal 700259"))
	_, err := regexp.CompilePOSIX(`\d+`)
	fmt.Println("eroare:", err)
}

Rezultat

Compile:      Iași
CompilePOSIX: Iași-Vaslui
700259
eroare: error parsing regexp: invalid escape sequence: `\d`

Greșeli frecvente

  • Folosești MustCompile pentru expresii venite de la utilizator: o greșeală oprește tot programul. Pentru acestea folosește Compile și verifică eroarea.
  • Compilezi expresia în interiorul unei funcții chemate des. Mut-o într-o variabilă globală, compilată o singură dată.

Comenzi înrudite

  • regexp.MatchString: Verifică dintr-un singur apel dacă un text (string, []byte sau un RuneReader) se potrivește cu o expresie regulată.
  • regexp.Regexp.FindString: Găsește prima potrivire (FindString), toate potrivirile (FindAllString) sau poziția primei potriviri (FindStringIndex).
  • regexp.Regexp.FindStringSubmatch: Returnează potrivirea împreună cu grupurile din paranteze; SubexpNames dă numele grupurilor (?P<nume>…).
  • regexp.Regexp.ReplaceAllString: Înlocuiește toate potrivirile cu un text (care poate folosi grupurile $1, ${nume}) sau cu rezultatul unei funcții.
  • regexp.Regexp.Split: Împarte textul în bucăți acolo unde se potrivește expresia regulată, de exemplu după orice combinație de virgule și spații.