Regular Expressions
Giriga och lata kvantifierare
Sök…
parametrar
Kvantifierare | Beskrivning |
---|---|
? | Matcha föregående tecken eller subexpression 0 eller 1 gånger (helst 1). |
* | Matcha föregående tecken eller subexpression 0 eller flera gånger (så många som möjligt). |
+ | Matcha föregående karaktär eller subexpression en eller flera gånger (så många som möjligt). |
{n} | Matcha föregående karaktär eller subexpression exakt n gånger. |
{min,} | Matcha föregående karaktär eller subexpression min eller flera gånger (så många som möjligt). |
{0,max} | Matcha föregående tecken eller subexpression max eller färre gånger (så nära max som möjligt). |
{min,max} | Matcha föregående karaktär eller subexpression minst min gånger men högst max gånger (så nära max som möjligt). |
Lata kvantifierare | Beskrivning |
?? | Matcha föregående tecken eller subexpression 0 eller 1 gånger (helst 0). |
*? | Matcha föregående karaktär eller subexpression 0 eller flera gånger (så få som möjligt). |
+? | Matcha föregående tecken eller subexpression en eller flera gånger (så få som möjligt). |
{n}? | Matcha föregående karaktär eller subexpression exakt n gånger. Ingen skillnad mellan giriga och lata versioner. |
{min,}? | Matcha föregående karaktär eller subexpression min eller flera gånger (så nära min som möjligt). |
{0,max}? | Matcha föregående tecken eller subexpression max eller färre gånger (så få som möjligt). |
{min,max}? | Matcha föregående tecken eller subexpression minst min gånger men högst max gånger (så nära min som möjligt). |
Anmärkningar
girighet
En girig kvantifierare försöker alltid upprepa undermönstret så många gånger som möjligt innan man utforskar kortare matchningar genom backspårning.
I allmänhet matchar ett girigt mönster den längsta möjliga strängen.
Som standard är alla kvantifierare giriga.
Lättja
En lat (även kallad icke-girig eller motvillig ) kvantifierare försöker alltid upprepa undermönstret så få gånger som möjligt innan man utforskar längre matcher genom expansion.
I allmänhet matchar ett lat mönster den kortast möjliga strängen.
För att göra kvantifierare lata, bara bifoga ?
till den befintliga kvantifieraren, t.ex. +?
, {0,5}?
.
Begreppet girighet och lathet finns bara i backtrackingmotorer
Uppfattningen om giriga / lata kvantifierare finns bara i backtracking-regexmotorer. I icke-backtracking-regex-motorer eller POSIX-kompatibla regex-motorer anger kvantifierare endast övre gränsen och nedre gränsen för repetitionen, utan att ange hur man hittar matchen - dessa motorer kommer alltid att matcha den längsta längst till vänster oavsett.
Girighet kontra lathet
Följande input:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
Vi kommer att använda två mönster: ett girigt: A.*Z
och ett lat: A.*?Z
Dessa mönster ger följande matchningar:
-
A.*Z
ger 1 match:AlazyZgreeedyAlaaazyZ
(exempel: Regex101 , Rubular ) -
A.*?Z
ger 2 matchningar:AlazyZ
ochAlaaazyZ
(exempel: Regex101 , Rubular )
Fokusera först på vad A.*Z
gör. När den matchade den första A
,. .*
, Som är girig, försöker sedan matcha så många .
som möjligt.
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\________________________/
A.* matched, Z can't match
Eftersom Z
inte matchar måste motorn backtracks och .*
Måste matcha en färre .
:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\_______________________/
A.* matched, Z can't match
Detta händer ytterligare några gånger tills det äntligen kommer till detta:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\__________________/
A.* matched, Z can now match
Nu kan Z
matcha, så det övergripande mönstret matchar:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\___________________/
A.*Z matched
Däremot matchar den motvilliga (lata) repetitionen i A.*?Z
först så få .
som möjligt och sedan ta mer .
som nödvändigt. Detta förklarar varför den hittar två matchningar i ingången.
Här är en visuell representation av vad de två mönstren matchade:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\____/l \______/l l = lazy
\_________g_________/ g = greedy
Exempel baserat på svar gjorda av polygenelubricants .
POSIX-standarden inkluderar inte ?
operatör, så många POSIX regex-motorer har inte lat matchning. Även om refactoring, särskilt med det "största tricket någonsin" , kan hjälpa till att matcha i vissa fall, är det enda sättet att få sann lata matchning att använda en motor som stöder den.
Gränser med flera matcher
När du har en inmatning med väl definierade gränser och förväntar dig mer än en matchning i din sträng, har du två alternativ:
- Använda lata kvantifierare;
- Med hjälp av en negerad karaktärsklass.
Tänk på följande:
Du har en enkel mallmotor, du vill byta ut underlag som $[foo]
där foo
kan vara vilken sträng som helst. Du vill ersätta denna substring med allt som baseras på delen mellan []
.
Du kan prova något som \$\[(.*)\]
Och sedan använda den första bildgruppen.
Problemet med detta är om du har en sträng som something $[foo] lalala $[bar] something else
din match att vara
something $[foo] lalala $[bar] something else
| \______CG1______/|
\_______Match______/
Fångstgruppen är foo] lalala $[bar
som kanske eller inte är giltig.
Du har två lösningar
Använda lathet: I det här fallet är
*
lata ett sätt att hitta rätt saker. Så du ändrar ditt uttryck till\$\[(.*?)\]
Med hjälp av negerat teckenklass:
[^\]]
ändrar du ditt uttryck till\$\[([^\]]*)\]
.
I båda lösningarna blir resultatet samma:
something $[foo] lalala $[bar] something else
| \_/| | \_/|
\____/ \____/
Med fångstgruppen är foo
respektive bar
.
Att använda negerad karaktärsklass minskar problem med backspårning och kan spara din CPU mycket tid när det gäller stora ingångar.