
Grådig vs. lat matching i regex: hvorfor mønsteret ditt griper for mye
Publisert 24. juli 2026
Du skriver <b>.*</b> for å hente ut innholdet i en fet-tekst-tag, tester den på <b>Hello</b>, og den fungerer perfekt. Så kjører du den på ekte HTML med to fet-tekst-tagger på samme linje — <b>Hello</b> and <b>World</b> — og i stedet for to treff får du ett kjempetreff som spenner over begge taggene. Dette er ikke en feil i regex-motoren din; det er standardoppførselen til *, + og {n,m}, og det har en løsning på ett tegn når du vet hva som skjer.
Hvorfor .* griper mer enn du forventer
Som standard er kvantifikatorer i regex grådige — .* betyr ikke «match noen tegn», det betyr «match så mange tegn som mulig, og trekk deg bare tilbake hvis resten av mønsteret absolutt krever det».
Gå gjennom <b>.*</b> mot <b>Hello</b> and <b>World</b> steg for steg:
<b>matcher den første<b>..*starter med å konsumere hele resten av strengen — alt frem til slutten, inkludert den andre<b>World</b>.- Motoren må så finne
</b>for å fullføre matchen, så den begynner å trekke seg tilbake fra slutten av.*ett tegn av gangen. - Det første stedet (sett bakover fra slutten) der
</b>passer, er den aller siste</b>i strengen — ikke den første den «logisk» burde stoppet ved.
Så treffet ender opp med å bli <b>Hello</b> and <b>World</b> i sin helhet, fordi grådig matching alltid prøver den lengst mulige strengen først og bare krymper den så lite som nødvendig for at resten av mønsteret skal lykkes.
Løsningen: gjør kvantifikatoren lat med ?
Å legge til et ? rett etter en kvantifikator snur den fra grådig til lat (også kalt «non-greedy» eller «reluctant»): *?, +?, ??, {n,m}?.
En lat kvantifikator gjør det motsatte: den starter med å matche så få tegn som mulig, og utvider seg bare hvis resten av mønsteret ikke kan lykkes ennå.
<b>.*?</b> mot samme streng:
<b>matcher den første<b>..*?starter med å matche null tegn.- Motoren sjekker: matcher
</b>akkurat her? Nei (vi er ved «Hello…», ikke ennå ved en</b>) — så den utvider.*?med nøyaktig ett tegn og sjekker igjen. - Dette gjentas tegn for tegn helt til
.*?har konsumert nøyaktigHello, hvorpå</b>matcher umiddelbart.
Resultat: <b>Hello</b> og <b>World</b> kommer tilbake som to separate treff, som nesten alltid er det du faktisk ønsket når du parser tag-lignende eller skilletegn-lignende strukturer.
Når du faktisk vil ha grådig (det er ikke bare «feil standard»)
Grådig er ikke en feil i språket — det er riktig for et annet, like vanlig tilfelle: å matche den ytterste grensen av noe, ikke den minste enheten inni det. Hvis du henter ut «alt mellom den første { og den siste }» i en blob med JSON-lignende tekst (for eksempel for å gripe et helt objekt uansett nøsting), er grådig akkurat riktig, og lat ville stoppet ved den første indre } i stedet, og gitt deg et avkuttet, ugyldig fragment.
Tommelfingerregelen: lat for gjentatte små avgrensede biter (tagger, tekst i anførselstegn, listeelementer); grådig for «grip hele det ytre spennet».
Hurtigreferanse
| Mønster | Oppførsel | Bruk det når |
|---|---|---|
.*, .+, {n,m} |
Grådig — matcher lengst mulig | Du vil ha det ytterste spennet, eller det bare finnes ett treff i strengen |
.*?, .+?, {n,m}? |
Lat — matcher kortest mulig | Du har flere lignende avgrensede biter og vil ha hver av dem separat |
Hvis du er usikker på hva et mønster faktisk gjør på din ekte input i stedet for teststrengen din, gjør det å kjøre det mot den faktiske teksten med flere treff i en regex-tester med live treff-utheving forskjellen umiddelbart synlig — du vil se én kjempeblokk utheves for grådig, mot flere separate for lat, noe som vanligvis er raskere enn å resonnere seg gjennom det tegn for tegn.