regexp.Regexp.FindStringSubmatch în Go

Returnează potrivirea împreună cu grupurile din paranteze; SubexpNames dă numele grupurilor (?P<nume>…).

Sintaxă
func (re *Regexp) FindStringSubmatch(s string) []string
func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string
func (re *Regexp) SubexpNames() []string

Ce face regexp.Regexp.FindStringSubmatch

Parantezele dintr-o expresie regulată formează grupuri (subexpresii). re.FindStringSubmatch(s) returnează un slice în care elementul 0 este toată potrivirea, iar elementele 1, 2, … sunt textele prinse de fiecare grup, în ordinea parantezelor. Dacă nu există potrivire, returnează nil.

re.FindAllStringSubmatch(s, n) face același lucru pentru toate potrivirile și returnează un slice de slice-uri. n = -1 înseamnă toate.

Grupurile pot avea nume: (?P<an>\d{4}) sau, din Go 1.22, (?<an>\d{4}). re.SubexpNames() returnează numele lor, în aceeași ordine ca rezultatul lui FindStringSubmatch (elementul 0 este mereu gol). Cu re.SubexpIndex("an") afli direct poziția unui grup.

Parametri

Parametru Descriere
s Textul.
n La FindAllStringSubmatch: numărul maxim de potriviri.

Ce returnează

FindStringSubmatch: []string (potrivire + grupuri) sau nil. FindAllStringSubmatch: [][]string. SubexpNames: []string cu numele grupurilor.

Exemple

Exemplul 1: Desfacerea unei date

package main

import (
	"fmt"
	"regexp"
)

func main() {
	re := regexp.MustCompile(`(\d{2})\.(\d{2})\.(\d{4})`)
	m := re.FindStringSubmatch("Examenul are loc pe 15.06.2026, la ora 9.")
	fmt.Printf("%q\n", m)
	fmt.Println("zi:", m[1], "lună:", m[2], "an:", m[3])
	fmt.Println(re.FindStringSubmatch("fără dată") == nil)
}

Rezultat

["15.06.2026" "15" "06" "2026"]
zi: 15 lună: 06 an: 2026
true

Exemplul 2: Toate perechile nume=notă

package main

import (
	"fmt"
	"regexp"
)

func main() {
	re := regexp.MustCompile(`(\p{L}+)=(\d+)`)
	text := "Ana=10, Ștefan=9, Ion=7"
	for _, m := range re.FindAllStringSubmatch(text, -1) {
		fmt.Printf("%-7s nota %s\n", m[1], m[2])
	}
}

Rezultat

Ana     nota 10
Ștefan  nota 9
Ion     nota 7

Exemplul 3: Grupuri cu nume și SubexpNames

package main

import (
	"fmt"
	"regexp"
)

func main() {
	re := regexp.MustCompile(`(?P<judet>[A-Z]{1,2}) (?P<numar>\d{2,3}) (?P<litere>[A-Z]{3})`)
	m := re.FindStringSubmatch("Mașina are numărul IS 07 ABC.")
	nume := re.SubexpNames()
	fmt.Printf("%q\n", nume)
	for i := 1; i < len(m); i++ {
		fmt.Printf("%s = %s\n", nume[i], m[i])
	}
	fmt.Println("județ:", m[re.SubexpIndex("judet")])
}

Rezultat

["" "judet" "numar" "litere"]
judet = IS
numar = 07
litere = ABC
județ: IS

Greșeli frecvente

  • Accesezi m[1] fără să verifici m != nil. Dacă textul nu se potrivește, programul se oprește cu index out of range.
  • Uiți că m[0] este toată potrivirea și numeri grupurile de la 0.
  • Adaugi paranteze doar pentru grupare și strici numerotarea. Pentru grupare fără captură folosește (?:…).

Comenzi înrudite

  • regexp.Regexp.FindString: Găsește prima potrivire (FindString), toate potrivirile (FindAllString) sau poziția primei potriviri (FindStringIndex).
  • regexp.Regexp.ReplaceAllString: Înlocuiește toate potrivirile cu un text (care poate folosi grupurile $1, ${nume}) sau cu rezultatul unei funcții.
  • regexp.Regexp: O expresie regulată compilată: o creezi o dată cu Compile sau MustCompile și o folosești de oricâte ori (MatchString, Find…, Replace…).