Regular expression | Norsk oversettelse

Navigasjon

Denne opplæringen er bare én stor HTML-fil, med noen få grafikk brukt underveis. Bare bla ned for å lese den. Utskrift kan bryte noen leksjoner i midten – men da betalte du ikke mye for å få dette.

Hvem er denne opplæringen for?

Denne opplæringen er rettet mot brukere og programmerere som har begynt å jobbe med verktøy som bruker regulære uttrykk, men som ikke er helt komfortable med forviklingene ved dem. Selv brukere som kanskje har brukt regulære uttrykk tidligere, men har glemt noen av detaljene kan ha nytte av dette som en oppfriskning.

Etter å ha fullført denne opplæringen vil du ennå ikke være en ekspert på å bruke regulære uttrykk til beste fordel. Men denne opplæringen kombinert med mye øvelse med varierende tilfeller handler om alt du trenger for å være ekspert. Konseptene med regulære uttrykk er ekstremt enkle og kraftige. . . det er deres applikasjon som krever litt arbeid.

Hva er egentlig et regulært uttrykk?

Les veiledningen for å få det lange svaret. Det korte svaret er at et regulært uttrykk er en kompakt måte å beskrive komplekse mønstre i tekster på. Du kan bruke dem til å søke etter mønstre og, når de er funnet, til å endre mønstrene på komplekse måter. De kan også brukes til å starte programmatiske handlinger som er avhengige av mønstre.

En direkte kommentar fra programmerere er verdt å tenke på: «Noen ganger har du et programmeringsproblem og det virker som om den beste løsningen er å bruke regulære uttrykk; nå har du to problemer.» Regelmessige uttrykk er utrolig kraftige og dypt uttrykksfulle. Det er selve grunnen til å skrive dem er like utsatt for feil som å skrive hvilken som helst annen kompleks programmeringskode. Det er alltid bedre å løse et genuint enkelt problem på en enkel måte; når du går utover det enkle, tenk på regulære uttrykk.

Hvilke verktøy bruker regulære uttrykk?

Et stort antall verktøy inneholder regulære uttrykk som en del av funksjonaliteten deres. Unix-orienterte kommandolinjeverktøy som grepsed, og awker for det meste wrapper for prosessering av regulære uttrykk. Mange tekstredigerere tillater søk og/eller erstatning basert på regulære uttrykk. Mange programmeringsspråk, spesielt skriptspråk som Perl, Python og TCL, bygger regulære uttrykk inn i hjertet av språket. Selv de fleste kommandolinjeskall, som Bash eller Windows-konsollen, tillater begrensede regulære uttrykk som en del av kommandosyntaksen.

Det er noen få variasjoner i syntaks for regulære uttrykk mellom forskjellige verktøy som bruker dem. Noen verktøy legger til forbedrede funksjoner som ikke er tilgjengelig overalt. Generelt, for de enkleste tilfellene, vil denne opplæringen bruke eksempler basert på grepeller sed. For noen flere eksotiske muligheter vil Perl- eller Python-eksempler bli valgt. For det meste vil eksempler fungere hvor som helst; men sjekk dokumentasjonen på ditt eget verktøy for syntaksvariasjoner og -funksjoner.

Merknad om presentasjon

For å presentere eksempler i denne opplæringen, vil regulære uttrykk beskrevet være omgitt av skråstreker. Denne stilen for å avgrense regulære uttrykk brukes av sedawk, perl og andre verktøy. Et eksempel kan for eksempel nevne:

/[A-Z]+(abc|xyz)*/

Les videre for å forstå dette eksemplet, for nå er det bare å forstå at det faktiske regulære uttrykket er alt mellom skråstrekene.

Mange eksempler vil bli ledsaget av en illustrasjon som viser et regulært uttrykk, og en tekst som er uthevet for hver kamp på det uttrykket.

Ta kontakt med

David Mertz er en skribent, en programmerer og en lærer, som alltid forsøker å forbedre kommunikasjonen sin til lesere (og opplæringsdeltakere). Han tar gjerne imot kommentarer, vennligst send dem til < mertz@gnosis.cx >.

Hvor skal du gå herfra…

Etter at du har fullført denne opplæringen vil du ha sett det grunnleggende (og litt avanserte emner) for regulære uttrykk. Det beste du kan gjøre er å begynne å bruke dem i virkelige problemer. Det første du må se på er dokumentasjonen som følger med det spesielle verktøyet du bruker. Utover det har en rekke trykte bøker gode forklaringer på vanlige uttrykk, ofte implementert med spesifikke verktøy. Noen bøker skaperen av denne opplæringen har hatt nytte av er:

  • Mastering Regular Expressions , Friedl, Jeffrey EF, O’Reilly, Cambridge, MA 1997.
  • sed & awk , Dale Dougherty & Arnold Robbins, O’Reilly, Cambridge, MA 1997.
  • Programmering Perl , Larry Wall, Tom Christiansen & Randal L. Schwartz, O’Reilly, Cambridge, MA 1996.
  • TCL/TK i et nøtteskall , Paul Raines og Jeff Tranter, O’Reilly, Cambridge, MA 1999.
  • Python Pocket Reference , Mark Lutz, O’Reilly, Cambridge, MA 1998.
  • A Practical Guide to Linux , Mark G. Sobell, Addison Wesley, Reading, MA 1997.

Matchende mønstre i tekst: Grunnleggende


Karakterbokstaver

/a/

Mary had a little lamb.
And everywhere that Mary
went, the lamb was sure
to go.

/Mary/

Mary had a little lamb.
And everywhere that Mary
went, the lamb was sure
to go.

Det aller enkleste mønsteret som matches av et regulært uttrykk er et bokstavelig tegn eller en sekvens av bokstavelige tegn. Alt i målteksten som består av nøyaktig de tegnene i nøyaktig den oppførte rekkefølgen vil samsvare. En liten bokstav er ikke identisk med den store versjonen, og omvendt. Et mellomrom i et regulært uttrykk samsvarer forresten med et bokstavelig mellomrom i målet (dette er i motsetning til de fleste programmeringsspråk eller kommandolinjeverktøy, der mellomrom skiller nøkkelord).

«Rømte» karakterer bokstavelig

/.*/

Special characters must be escaped.*

/\.\*/
Special characters must be escaped.*

En rekke tegn har spesiell betydning for vanlige uttrykk. Et symbol med en spesiell betydning kan matches, men for å gjøre det må du prefiksere det med skråstrek-tegnet (dette inkluderer selve skråstrek-tegnet: for å matche ett skråstrek i målet, bør det vanlige uttrykket ditt inkludere «\\»).

Posisjonelle spesialtegn

/^Mary/

Mary had a little lamb.
And everywhere that Mary
went, the lamb was sure
to go.

/Mary$/

Mary had a little lamb.
And everywhere that Mary
went, the lamb was sure
to go.

To spesialtegn brukes i nesten alle regulære uttrykksverktøy for å markere begynnelsen og slutten av en linje: caret (^) og dollartegn ($). For å matche et skjema eller dollartegn som et bokstavelig tegn, må du unnslippe det (dvs. gå foran det med en omvendt skråstrek «\»).

En interessant ting med merket og dollartegnet er at de samsvarer med null- breddemønstre . Det vil si at lengden på strengen som matches av en indikator eller dollartegn i seg selv er null (men resten av det regulære uttrykket kan fortsatt avhenge av null-bredde-treffet). Mange regulære uttrykksverktøy gir et annet null-breddemønster for ordgrense (\b). Ord kan deles med mellomrom som mellomrom, tabulatorer, nye linjer eller andre tegn som null; ordgrensemønsteret samsvarer med det faktiske punktet der et ord starter eller slutter, ikke de spesielle mellomromstegnene.

«Jokertegn»-tegnet

/.a/ 

Mary had a little lamb.
And everywhere that Mary
went, the lamb was sure
to go.

I regulære uttrykk kan et punktum stå for et hvilket som helst tegn. Normalt er linjeskifttegnet ikke inkludert, men de fleste verktøy har valgfrie brytere for å tvinge inkludering av linjeskifttegnet også. Å bruke en periode i et mønster er en måte å kreve at «noe» skal skje her, uten å måtte bestemme seg for hva.

Brukere som er kjent med DOS-kommandolinjejokertegn vil kjenne spørsmålstegnet som å fylle rollen som «en eller annen karakter» i kommandomasker. Men i regulære uttrykk har spørsmålstegnet en annen betydning, og perioden brukes som jokertegn.

Gruppering av regulære uttrykk

/(Mary)( )(had)/ 

Mary had a little lamb.
And everywhere that Mary
went, the lamb was sure
to go.

Et regulært uttrykk kan ha bokstavelige tegn i seg, og også null-bredde posisjonsmønstre. Hvert bokstavelig tegn eller posisjonsmønster er et atom i et regulært uttrykk. Du kan også gruppere flere atomer sammen til et lite regulært uttrykk som er en del av et større regulært uttrykk. Man kan være tilbøyelig til å kalle en slik gruppering et «molekyl», men normalt kalles det også et atom.

I eldre Unix-orienterte verktøy som grep, må underuttrykk grupperes med escaped parenteser, f.eks /\(Mary\)/. I Perl og de nyeste verktøyene (inkludert egrep) gjøres gruppering med bare parenteser, men å matche en bokstavelig parentes krever at man unnslipper den i mønsteret (eksemplet til siden følger Perl).

Karakterklasser

/[a-z]a/ 

Mary had a little lamb.
And everywhere that Mary
went, the lamb was sure
to go.

I stedet for å navngi bare et enkelt tegn, kan du inkludere et mønster i et regulært uttrykk som samsvarer med et sett med tegn.

Et sett med tegn kan gis som en enkel liste innenfor hakeparenteser, /[aeiou]/vil f.eks. matche en enkelt liten vokal. For bokstav- eller tallområder kan du også bruke bare den første og siste bokstaven i et område, med en bindestrek i midten, f.eks. /[A-Ma-m]/vil matche alle små eller store bokstaver i den første halvdelen av alfabetet.

Mange verktøy for regulære uttrykk gir også snarveier i escape-stil til den mest brukte tegnklassen, for eksempel \sfor et mellomromstegn og \dfor et siffer. Du kan alltid definere disse tegnklassene med hakeparenteser, men snarveiene kan gjøre regulære uttrykk mer kompakte og mer lesbare.

Komplementoperatør

/[^a-z]a/ 

Mary had a little lamb.
And everywhere that Mary
went, the lamb was sure
to go.

Caret-symbolet kan faktisk ha to forskjellige betydninger i regulære uttrykk. Mesteparten av tiden betyr det å matche null-lengdemønsteret for linjebegynnelse. Men hvis den brukes i begynnelsen av en karakterklasse, reverserer den betydningen av karakterklassen. Alt som ikke er inkludert i det oppførte tegnsettet er matchet.

Veksling av mønstre

/cat|dog|bird/

The pet store sold cats, dogs, and birds.

/=first|second=/

=first first= # =second second= # =first= # =second=

/(=)(first)|(second)(=)/

=first first= # =second second= # =first= # =second=

/=(first|second)=/

=first first= # =second second= # =first= # =second=

Å bruke karakterklasser er en måte å indikere at enten en eller annen ting kan forekomme på et bestemt sted. Men hva om du vil spesifisere at ett av to hele underuttrykk forekommer i en posisjon i det regulære uttrykket? Til det bruker du alterneringsoperatoren, den vertikale linjen («|»). Dette er symbolet som også brukes til å indikere en pipe i Unix/DOS-skall, og kalles noen ganger for pipe-karakteren.

Pipetegnet i et regulært uttrykk indikerer en veksling mellom alt i gruppen som omslutter det. Hva dette betyr er at selv om det er flere grupper til venstre og høyre for en rørkarakter, spør vekslingen grådig om alt på begge sider. For å velge omfanget av vekslingen, må du definere en gruppe som omfatter mønstrene som kan samsvare. Eksemplet illustrerer dette.

Den grunnleggende abstrakte kvantifisereren

/@(=#=)*@/ 

Match with zero in the middle: @@
Subexpresion occurs, but...: @=#=ABC@
Lots of occurrences: @=#==#==#==#==#=@
Must repeat entire pattern: @=#==#=#==#=@

En av de kraftigste og mest vanlige tingene du kan gjøre med regulære uttrykk er å spesifisere hvor mange ganger et atom forekommer i et komplett regulært uttrykk. Noen ganger vil du spesifisere noe om forekomsten av et enkelt tegn, men veldig ofte er du interessert i å spesifisere forekomsten av en tegnklasse eller et gruppert underuttrykk.

Det er bare én kvantifier inkludert i «grunnleggende» syntaks for regulære uttrykk, stjernen («*»); på engelsk har dette betydningen «noen eller ingen» eller «null eller mer.» Hvis du vil spesifisere at et hvilket som helst antall av et atom kan forekomme som en del av et mønster, følger du atomet med en stjerne.

Uten kvantifiserere tjener ikke gruppering av uttrykk egentlig så mye hensikt, men når vi først kan legge til en kvantifiserer til et underuttrykk, kan vi si noe om forekomsten av underuttrykket som helhet. Ta en titt på eksempelet.

Matchende mønstre i tekst: Middels


Mer abstrakte kvantifiserere

/A+B*C?D/

AAAD
ABBBBCD
BBBCD
ABCCD
AAABBBC

På en viss måte kvantifiserer mangelen på et kvantifiseringssymbol etter et atom atomet uansett: det sier at atomet forekommer nøyaktig én gang . Utvidede regulære uttrykk (som de fleste verktøy støtter) legger til noen få andre nyttige tall til «nøyaktig en gang» og «null eller flere ganger.» Plusstegnet («+») betyr «en eller flere ganger» og spørsmålstegnet («?») betyr «null eller én ganger.» Disse kvantifikatorene er de klart vanligste oppregningene du ender opp med å navngi.

Hvis du tenker deg om, kan du se at de utvidede regulære uttrykkene faktisk ikke lar deg «si» noe de grunnleggende ikke gjør. De lar deg bare si det på en kortere og mer lesbar måte. For eksempel, » (ABC)+» tilsvarer » (ABC)(ABC)*«; og » X(ABC)?Y» tilsvarer » XABCY|XY«. Hvis atomene som kvantifiseres i seg selv er kompliserte grupperte underuttrykk, kan spørsmålstegnet og plusstegnet gjøre ting mye kortere.

Numeriske kvantifiserere

/a{5} b{,6} c{4,8}/

aaaaa bbbbb ccccc
aaa bbb ccc
aaaaa bbbbbbbbbbbbbb ccccc

/a+ b{3,} c?/

aaaaa bbbbb ccccc
aaa bbb ccc
aaaaa bbbbbbbbbbbbbb ccccc

/a{5} b{6,} c{4,8}/

aaaaa bbbbb ccccc
aaa bbb ccc
aaaaa bbbbbbbbbbbbbb ccccc

Ved å bruke utvidede regulære uttrykk kan du spesifisere antall vilkårlige mønsterforekomster ved å bruke en mer detaljert syntaks enn spørsmålstegn, plusstegn og stjernekvantifikatoren. De krøllete klammeparentesene («{» og «}») kan omgi en nøyaktig telling av hvor mange forekomster du leter etter.

Den mest generelle formen for kvantifiseringen med krøllete klammeparenteser bruker to områdeargumenter (det første må ikke være større enn det andre, og begge må være ikke-negative heltall). Antall forekomster spesifiseres på denne måten for å falle mellom minimum og maksimum som er angitt (inklusive). Som stenografi kan begge argumentene stå tomme: i så fall spesifiseres minimum/maksimum som henholdsvis null/uendelig. Hvis bare ett argument brukes (uten komma), blir nøyaktig det antallet forekomster matchet.

Tilbakereferanser

/(abc|xyz) \1/

jkl abc xyz
jkl xyz abc
jkl abc abc
jkl xyz xyz

/(abc|xyz) (abc|xyz)/

jkl abc xyz
jkl xyz abc
jkl abc abc
jkl xyz xyz

Et kraftig alternativ for å lage søkemønstre er å spesifisere at et underuttrykk som ble matchet tidligere i et regulært uttrykk, matches igjen senere i uttrykket. Vi gjør dette ved å bruke tilbakereferanser . Tilbakereferanser er navngitt med tallene 1 til 9, foran skråstrek/escape-tegnet når de brukes på denne måten. Disse tilbakereferansene refererer til hver påfølgende gruppe i kampmønsteret, som i /(one)(two)(three)/\1\2\3/. Hver nummerert tilbakereferanse refererer til gruppen som i dette eksemplet har ordet som tilsvarer nummeret.

Det er viktig å merke seg noe eksemplet illustrerer. Det som blir matchet av en tilbakereferanse er den samme bokstavelige strengen som matches første gang, selv om mønsteret som matchet strengen kunne ha matchet andre strenger. Å bare gjenta det samme grupperte underuttrykket senere i det regulære uttrykket samsvarer ikke med de samme målene som å bruke en tilbakereferanse (men du må bestemme hva det er du faktisk vil matche i begge tilfeller).

Tilbakereferanser refererer tilbake til det som skjedde i de tidligere grupperte uttrykkene, i den rekkefølgen de grupperte uttrykkene oppstod. På grunn av navnekonvensjonen (\1-\9), begrenser mange verktøy deg til ni tilbakereferanser. Noen verktøy tillater faktisk navngiving av tilbakereferanser og/eller lagring av dem til programvariabler. De mer avanserte delene av denne opplæringen berører disse emnene

Ikke match mer enn du ønsker

/th.*s/

-- I want to match the words that start
-- with 'th' and end with 's'.
this
thus
thistle
this line matches too much

Kvantifiserere i regulære uttrykk er grådige . Det vil si at de matcher så mye de kan.

Sannsynligvis den enkleste feilen å gjøre når du komponerer regulære uttrykk, er å matche for mye . Når du bruker en kvantifiserer, vil du at den skal matche alt (av riktig sort) til det punktet hvor du vil fullføre kampen. Men når du bruker «*», «+» eller numeriske kvantifiserere, er det lett å glemme at den siste biten du leter etter kan forekomme senere i en linje enn den du er interessert i.

Triks for å begrense fyrstikker

/th[^s]*./

-- I want to match the words that start
-- with 'th' and end with 's'.
this
thus
thistle
this line matches too much

Ofte hvis du finner ut at de regulære uttrykkene dine samsvarer for mye, er en nyttig prosedyre å omformulere problemet i tankene dine. I stedet for å tenke på «hva prøver jeg å matche senere i uttrykket?» spør deg selv «hva trenger jeg for å unngå matching i neste del?» Ofte fører dette til mer sparsommelige mønstertreff. Ofte er måten å unngå et mønster på å bruke komplementoperatoren og en tegnklasse. Se på eksempelet, og tenk på hvordan det fungerer.

Trikset her er at det er to forskjellige måter å formulere nesten samme sekvens på. Du kan enten tro at du vil fortsette å matche til du kommer til XYZ, eller du kan tenke at du vil fortsette å matche med mindre du kommer til XYZ. Disse er subtilt forskjellige.

For personer som har tenkt på grunnleggende sannsynlighet, oppstår det samme mønsteret. Sjansen for å kaste en 6 på en terning i ett kast er 1/6. Hva er sjansen for å kaste en 6 i seks kast? En naiv beregning setter oddsen til 1/6+1/6+1/6+1/6+1/6+1/6, eller 100%. Dette er selvfølgelig feil (tross alt er sjansen etter tolv kast ikke 200%). Den riktige beregningen er «hvordan unngår jeg å rulle en 6’er for seks kast?» — dvs. 5/6*5/6*5/6*5/6*5/6*5/6, eller ca. 33 %. Sjansen for å få en 6-er er den samme sjansen som å ikke unngå den (eller ca. 66%). Faktisk, hvis du forestiller deg å transkribere en serie terningkast, kan du bruke et regulært uttrykk på den skriftlige posten, og lignende tenkning gjelder.

Kommentarer til modifikasjonsverktøy

Ikke alle verktøy som bruker regulære uttrykk lar deg endre målstrenger. Noen finner ganske enkelt det matchede mønsteret; det mest brukte regulære uttrykksverktøyet er sannsynligvis grep, som kun er et verktøy for søk. Tekstredigerere, for eksempel, kan eller kan ikke tillate erstatning i deres regulære uttrykkssøkefunksjon. Som alltid, se dokumentasjonen på ditt individuelle verktøy.

Av verktøyene som lar deg endre måltekst, er det noen få forskjeller du bør huske på. Måten du faktisk spesifiserer erstatninger på vil variere mellom verktøyene: et tekstredigeringsprogram kan ha en dialogboks; kommandolinjeverktøy vil bruke skilletegn mellom match og erstatning, programmeringsspråk vil typisk kalle funksjoner med argumenter for match og erstatningsmønstre.

En annen viktig forskjell å huske på er hva som blir endret. Unix-orienterte kommandolinjeverktøy bruker vanligvis pipes og STDOUT for endringer i buffere, i stedet for å endre filer på plass. Bruk av en sedkommando vil for eksempel skrive endringene til konsollen, men vil ikke endre den opprinnelige målfilen. Det er mer sannsynlig at tekstredigerere eller programmeringsspråk faktisk endrer en fil på stedet.

En merknad om modifikasjonseksempler

For formålet med denne opplæringen vil eksempler fortsette å bruke sedskråstrekavgrensningene for stil. Spesielt vil eksemplene indikere erstatningskommandoen og den globale modifikatoren, som med » s/this/that/g«. Dette uttrykket betyr: «Erstatt strengen ‘dette’ med strengen ‘det’ overalt i målteksten.

Eksempler vil bestå av modifikasjonskommandoen, en inngangslinje og en utgangslinje. Utgangslinjen vil ha eventuelle endringer fremhevet. Hver input/output-linje vil også bli innledet av et mindre-enn eller større-en-symbol for å hjelpe til med å skille dem (rekkefølgen vil være som beskrevet også), noe som tyder på omdirigeringssymboler i Unix-skall.

Et eksempel på modifikasjon av bokstavelig streng

s/cat/dog/g 

< The zoo had wild dogs, bobcats, lions, and other wild cats.
> The zoo had wild dogs, bobdogs, lions, and other wild dogs.

La oss ta en titt på et par modifikasjonseksempler som bygger på det vi allerede har dekket. Denne erstatter ganske enkelt en bokstavelig tekst med en annen bokstavelig tekst. Søk-og-erstatt-muligheten til mange verktøy kan gjøre så mye, selv uten å bruke regulære uttrykk.

Et eksempel på modifikasjon av mønstermatch

s/cat|dog/snake/g 

< The zoo had wild dogs, bobcats, lions, and other wild cats.
> The zoo had wild snakes, bobsnakes, lions, and other wild snakes.

s/[a-z]+i[a-z]*/nice/g 

< The zoo had wild dogs, bobcats, lions, and other wild cats.
> The zoo had nice dogs, bobcats, nice, and other nice cats.

Mesteparten av tiden, hvis du bruker regulære uttrykk for å endre en måltekst, vil du ønske å matche mer generelle mønstre enn bare bokstavelige strenger. Uansett hva som matches er det som blir erstattet (selv om det er flere forskjellige strenger i målet)

Modifikasjon ved hjelp av tilbakereferanser

s/([A-Z])([0-9]{2,4}) /\2:\1 /g 

< A37 B4 C107 D54112 E1103 XXX
> 37:A B4 107:C D54112 1103:E XXX

Det er fint å kunne sette inn en fast streng overalt hvor et mønster forekommer i en måltekst. Men ærlig talt, å gjøre det er ikke veldig kontekstsensitivt. Mange ganger ønsker vi ikke bare å sette inn faste strenger, men heller å sette inn noe som har mye mer relasjon til de matchede mønstrene. Heldigvis kommer tilbakereferanser oss til unnsetning her. Du kan bruke tilbakereferanser i selve mønstertreffene, men det er enda mer nyttig å kunne bruke dem i erstatningsmønstre. Ved å bruke erstatningsbakreferanser kan du velge og vrake fra de matchede mønstrene for å bruke akkurat de delene du er interessert i.

For å gjøre det lettere å lese, vil underuttrykk grupperes med bare parenteser (som med Perl), i stedet for med escaped parenteser (som med sed).

Nok en advarsel om mismatching

Denne opplæringen har allerede advart om faren for å matche for mye med dine vanlige uttrykksmønstre. Men faren er så mye mer alvorlig når du gjør modifikasjoner, at det er verdt å gjenta. Hvis du erstatter et mønster som samsvarer med en større streng enn du trodde på da du komponerte mønsteret, har du potensielt slettet noen viktige data fra målet ditt.

Det er alltid en god idé å prøve ut de regulære uttrykkene dine på forskjellige måldata som er representative for produksjonsbruken din. Pass på at du matcher det du tror du matcher. En bortkommen kvantifier eller jokertegn kan få et overraskende stort utvalg av tekster til å matche det du trodde var et spesifikt mønster. Og noen ganger må du bare stirre på mønsteret ditt en stund, eller finne et annet sett med øyne, for å finne ut hva som egentlig skjer selv etter at du har sett hva som stemmer. Kjennskap kan skape forakt, men det gir også kompetanse.

Avanserte utvidelser for regulære uttrykk


Om avanserte funksjoner

Noen svært nyttige forbedringer er inkludert i noen regulære uttrykksverktøy. Disse forbedringene gjør ofte komposisjonen og vedlikeholdet av regulært uttrykk betydelig enklere. Men sjekk med ditt eget verktøy for å se hva som støttes.

Programmeringsspråket Perl er sannsynligvis det mest sofistikerte verktøyet for prosessering av regulære uttrykk, noe som forklarer mye av populariteten. Eksemplene som er illustrert vil bruke Perl-ish-kode for å forklare konsepter. Andre programmeringsspråk, spesielt andre skriptspråk som Python, har et lignende utvalg av forbedringer. Men for illustrasjonsformål gjenspeiler Perls syntaks mest de regulære uttrykksverktøyene den bygger på, som edexgrepsed, og awk.

Ikke-grådige kvantifiserere

/th.*s/

-- I want to match the words that start
-- with 'th' and end with 's'.
this line matches just right
this # thus # thistle

/th.*?s/

-- I want to match the words that start
-- with 'th' and end with 's'.
this # thus # thistle
this line matches just right

/th.*?s /

-- I want to match the words that start
-- with 'th' and end with 's'. (FINALLY!)
this # thus # thistle
this line matches just right

Tidligere i opplæringen ble problemene med å matche for mye diskutert, og noen løsninger ble foreslått. Noen regulære uttrykksverktøy er fine nok til å gjøre dette enklere ved å tilby valgfrie ikke-grådige kvantifiserere. Disse kvantifisereren tar så lite som mulig mens de fortsatt matcher det som kommer etterpå i mønsteret (i stedet for så mye som mulig).

Ikke-grådige kvantifiserere har samme syntaks som vanlige grådige, bortsett fra med kvantifisereren etterfulgt av et spørsmålstegn. Et ikke-grådig mønster kan for eksempel se slik ut: » /A[A-Z]*?B/«. På engelsk betyr dette «match en A, etterfulgt av bare så mange store bokstaver som er nødvendig for å finne en B.»

En liten ting å se etter er det faktum at mønsteret » /[A-Z]*?./» alltid vil samsvare med null store bokstaver. Hvis du bruker ikke-grådige kvantifiserere, se opp for å matche for lite , noe som er en symmetrisk fare.

Mønster-match-modifikatorer

/M.*[ise] /

MAINE # Massachusetts # Colorado #
mississippi # Missouri # Minnesota #

/M.*[ise] /i

MAINE # Massachusetts # Colorado #
mississippi # Missouri # Minnesota #

/M.*[ise] /gis

MAINE # Massachusetts # Colorado #
mississippi # Missouri # Minnesota #

Vi har allerede sett en mønster-match-modifikator i modifikasjonseksemplene: g lobal-modifikatoren. Faktisk, i mange regulære uttrykksverktøy, burde vi ha brukt «g»-modifikatoren for alle mønstertreffene våre. Uten «g», vil mange verktøy matche bare den første forekomsten av et mønster på en linje i målet. Så dette er en nyttig modifikator (men ikke en du nødvendigvis alltid vil bruke ). La oss se på noen andre.

Som en liten mnemonikk er det fint å huske ordet «gismo» (det virker til og med på en eller annen måte passende). De vanligste modifikatorene er:

  • g – Match globalt
  • i – Uavhengig av store og små bokstaver
  • s – Behandle streng som en enkelt linje
  • m – Behandle streng som flere linjer
  • o – Kompiler kun mønster én gang

Alternativet o er en implementeringsoptimalisering, og egentlig ikke et problem med regulære uttrykk (men det hjelper mnemonikken). Alternativet s ingle-line lar jokertegnet matche et nylinjekarakter (ellers gjør det ikke det). Alternativet med flere linjer får «^» og «$» til å matche begynnelsen og slutten av hver linje i målet, ikke bare begynnelsen/slutten av målet som helhet (med sedeller grepdette er standard). Det ufølsomme alternativet ignorerer forskjeller mellom store og små bokstaver.

Endring av tilbakereferanseatferd

s/([A-Z])(?:-[a-z]{3}-)([0-9]*)/\1\2/g

< A-xyz-37 # B:abcd:142 # C-wxy-66 # D-qrs-93
> A37 # B:abcd:42 # C66 # D93

Tilbakereferanse i erstatningsmønstre er veldig kraftig; men det er også enkelt å bruke mer enn ni grupper i et komplekst regulært uttrykk. Bortsett fra å bruke opp de tilgjengelige tilbakereferansenavnene, er det ofte mer lesbart å referere til delene av et erstatningsmønster i sekvensiell rekkefølge. For å håndtere dette problemet tillater noen regulære uttrykksverktøy «gruppering uten tilbakereferanse.»

En gruppe som ikke også skal behandles som en tilbakereferanse har et spørsmålstegn kolon i begynnelsen av gruppen, som i » (?:pattern).» Faktisk kan du bruke denne syntaksen selv når tilbakereferansene dine er i selve søkemønsteret.

Navngi tilbakereferanser

import re
txt = "A-xyz-37 # B:abcd:142 # C-wxy-66 # D-qrs-93"
print re.sub("(?P<prefix>[A-Z])(-[a-z]{3}-)(?P<id>[0-9]*)",
             "\g<prefix>\g<id>", txt) 

A37 # B:abcd:42 # C66 # D93

Språket Python tilbyr en spesielt hendig syntaks for virkelig komplekse mønsterbakreferanser. I stedet for bare å leke med nummereringen av matchede grupper, kan du gi dem et navn.

Syntaksen for å bruke regulære uttrykk i Python er en standard programmeringsspråkfunksjon/-metodestil for kall, i stedet for sedskråstrek-avgrensere i Perl- eller -stil. Sjekk ditt eget verktøy for å se om det støtter denne funksjonen.

Fremtidspåstander

s/([A-Z]-)(?=[a-z]{3})([a-z0-9]* )/\2\1/g

< A-xyz37 # B-ab6142 # C-Wxy66 # D-qrs93
> xyz37A- # B-ab6142 # C-Wxy66 # qrs93D-

s/([A-Z]-)(?![a-z]{3})([a-z0-9]* )/\2\1/g

< A-xyz37 # B-ab6142 # C-Wxy66 # D-qrs93
> A-xyz37 # ab6142B- # Wxy66C- # D-qrs93

Et annet triks med avanserte verktøy for regulære uttrykk er «lookahead-påstander». Disse ligner på vanlig gruppert underuttrykk, bortsett fra at de faktisk ikke fanger det de matcher. Det er to fordeler ved å bruke fremsynspåstander. På den ene siden kan en lookahead-påstand fungere på samme måte som en gruppe som ikke er tilbakereferert; det vil si at du kan matche noe uten å telle det i tilbakereferanser. Mer signifikant er det imidlertid at en påstand om et blikk fremover kan spesifisere at neste del av et mønster har en viss form, men la et annet underuttrykk faktisk gripe det (vanligvis for å tilbakerefere det andre underuttrykket).

Det er to typer framtidspåstander: positive og negative. Som du forventer, spesifiserer en positiv påstand at noe kommer etterpå, og en negativ spesifiserer at noe ikke kommer etterpå. Syntaksen for påstander om blikk framover er lik deres forbindelse med ikke-tilbakerefererte grupper: (?=pattern) for positive påstander og (?!pattern)for negative påstander.

Gjør regulære uttrykk mer lesbare

/               # identify URLs within a text file
          [^="] # do not match URLs in IMG tags like:
                # <img src="http://mysite.com/mypic.png">
http|ftp|gopher # make sure we find a resource type
          :\/\/ # ...needs to be followed by colon-slash-slash
      [^ \n\r]+ # stuff other than space, newline, tab is in URL
    (?=[\s\.,]) # assert: followed by whitespace/period/comma
/

The URL for my site is: http://mysite.com/mydoc.html.  You
might also enjoy ftp://yoursite.com/index.html for a good
place to download files.
    

I de senere eksemplene har vi begynt å se hvor kompliserte regulære uttrykk kan bli. Disse eksemplene er ikke det halve. Det er mulig å gjøre noen nesten absurd vanskelige å forstå ting med regulære uttrykk (men de som likevel er nyttige).

Det er to grunnleggende fasiliteter som noen av de mer avanserte regulære uttrykksverktøyene bruker for å tydeliggjøre uttrykk. Den ene er å la regulære uttrykk fortsette over flere linjer (ved å ignorere mellomrom som etterfølgende mellomrom og nye linjer). Den andre er å tillate kommentarer i regulære uttrykk. Noen verktøy lar deg gjøre en eller annen av disse tingene alene, men når det blir komplisert, gjør begge deler!

Eksemplet som er gitt bruker Perls e x tend-modifikator for å aktivere kommenterte regulære uttrykk med flere linjer. Se dokumentasjonen for ditt eget verktøy for detaljer om hvordan du komponerer disse.

Få gratis tilbud på alarm.