
Regex greedy vs. lazy matching: hvorfor dit mønster fanger for meget
Udgivet 24. jul. 2026
Du skriver <b>.*</b> for at fange indholdet i et fed-tag, tester det på <b>Hello</b>, og det virker perfekt. Så kører du det på rigtig HTML med to fed-tags på samme linje — <b>Hello</b> and <b>World</b> — og i stedet for to matches får du ét kæmpe match, der spænder over begge tags. Det her er ikke en fejl i din regex-motor; det er standardopførslen for *, + og {n,m}, og der er en løsning på ét tegn, når du først ved, hvad der sker.
Hvorfor .* fanger mere, end du forventer
Som standard er kvantorer i regex grådige (greedy) — .* betyder ikke “match nogle tegn”, det betyder “match så mange tegn som muligt, og træk kun i land, hvis resten af mønstret absolut kræver det.”
Følg <b>.*</b> mod <b>Hello</b> and <b>World</b> trin for trin:
<b>matcher det første<b>..*starter med at sluge hele resten af strengen — alt frem til slutningen, inklusive det andet<b>World</b>.- Motoren skal derefter finde
</b>for at fuldføre matchet, så den begynder at trække sig tilbage fra slutningen af.*ét tegn ad gangen. - Det første sted (set baglæns fra slutningen), hvor
</b>passer, er det allersidste</b>i strengen — ikke det første, den “logisk” burde stoppe ved.
Så matchet ender med at være hele <b>Hello</b> and <b>World</b>, fordi grådig matching altid først prøver den længst mulige streng og kun formindsker den lige akkurat nok til at resten af mønstret lykkes.
Løsningen: gør kvantoren doven med ?
Hvis du tilføjer et ? lige efter en kvantor, vender den fra grådig til doven (lazy) (også kaldet “non-greedy” eller “reluctant”): *?, +?, ??, {n,m}?.
En doven kvantor gør det modsatte: den starter med at matche så få tegn som muligt, og udvider kun, hvis resten af mønstret endnu ikke kan lykkes.
<b>.*?</b> mod samme streng:
<b>matcher det første<b>..*?starter med at matche nul tegn.- Motoren tjekker: matcher
</b>lige her? Nej (vi er ved “Hello…”, ikke ved et</b>endnu) — så udvider den.*?med præcis ét tegn og tjekker igen. - Det gentages tegn for tegn, indtil
.*?har slugt præcisHello, hvorefter</b>matcher med det samme.
Resultat: <b>Hello</b> og <b>World</b> kommer tilbage som to separate matches, hvilket næsten altid er det, du faktisk ville have, når du parser tag-lignende eller afgrænser-lignende strukturer.
Hvornår du faktisk vil have grådig (det er ikke bare “den forkerte standard”)
Grådig er ikke en fejl i sproget — det er korrekt til et andet, lige så almindeligt tilfælde: at matche den yderste grænse af noget, ikke den mindste enhed indeni. Hvis du udtrækker “alt mellem den første { og den sidste }” i en blob af JSON-lignende tekst (fx for at fange et helt objekt uanset indlejring), er grådig præcis rigtigt, og doven ville i stedet stoppe ved den første indre } og give dig et afkortet, ugyldigt fragment.
Tommelfingerreglen: doven til gentagne små afgrænsede stykker (tags, citerede strenge, listeelementer); grådig til “fang hele det ydre spænd.”
Hurtig oversigt
| Mønster | Opførsel | Brug det når |
|---|---|---|
.*, .+, {n,m} |
Grådig — matcher længst mulig | Du vil have det yderste spænd, eller der kun er ét match i strengen |
.*?, .+?, {n,m}? |
Doven — matcher kortest mulig | Du har flere lignende afgrænsede stykker og vil have hvert enkelt for sig |
Hvis du er i tvivl om, hvad et mønster faktisk gør på dit rigtige input frem for din teststreng, gør det at køre det mod den faktiske multi-match-tekst i en regex tester med live match-fremhævning forskellen øjeblikkeligt synlig — du vil se én kæmpe fremhævet blok for grådig versus flere separate for doven, hvilket som regel er hurtigere end at ræsonnere sig frem tegn for tegn.