Perl -kompatible vanlige uttrykk - Perl Compatible Regular Expressions

Perl -kompatible vanlige uttrykk
Originale forfattere Philip Hazel
Stabil utgivelse
PCRE2 10.38 og PCRE 8.45 / 15. juni 2021 ; 3 måneder siden ( 2021-06-15 )
Oppbevaringssted
Skrevet inn C
Operativsystem Kryssplattform
Type Mønster matchende bibliotek
Tillatelse BSD
Nettsted www.pcre.org

Perl Compatible Regular Expressions ( PCRE ) er et bibliotek skrevet i C , som implementerer en regulær uttrykksmotor , inspirert av funksjonene til Perl programmeringsspråk . Philip Hazel begynte å skrive PCRE sommeren 1997. PCREs syntaks er mye kraftigere og mer fleksibel enn noen av POSIX regulære uttrykkssmaker (BRE, ERE) og mange andre regulære uttrykksbiblioteker.

Mens PCRE opprinnelig var rettet mot funksjonsekvivalens med Perl, er de to implementeringene ikke helt likeverdige. Under PCRE 7.x- og Perl 5.9.x -fasen har de to prosjektene koordinert utvikling, med funksjoner som er portet mellom dem i begge retninger.

I 2015 ble en gaffel PCRE utgitt med et revidert programmeringsgrensesnitt (API). Den originale programvaren, nå kalt PCRE1 (8.xx -serien), har fått feil som er rettet, men ingen videre utvikling. Det anses nå (2020) som foreldet, og den nåværende utgivelsen på 8.45 er sannsynligvis den siste. Den nye PCRE2 -koden (10.xx -serien) har hatt en rekke utvidelser og kodingsforbedringer, og det er her utviklingen finner sted.

En rekke fremtredende open source-programmer , for eksempel Apache- og Nginx HTTP-servere, og PHP- og R- skriptspråk, inneholder PCRE-biblioteket; proprietær programvare kan gjøre det samme, ettersom biblioteket er BSD-lisensiert. Perl 5.10 er PCRE også tilgjengelig som erstatning for Perls standard motor for regulært uttrykk gjennom re::engine::PCREmodulen.

Biblioteket kan bygges på Unix, Windows og flere andre miljøer. PCRE2 distribueres med en POSIX C -innpakning, flere testprogrammer og verktøyprogrammet 'pcre2grep' bygget sammen med biblioteket.

Funksjoner

Støtte for kompilator akkurat i tide

Denne valgfrie funksjonen er tilgjengelig hvis den er aktivert når PCRE2 -biblioteket er bygget. Store ytelsesfordeler er mulige når (for eksempel) oppringningsprogrammet bruker funksjonen med kompatible mønstre som kjøres gjentatte ganger. Kompatibilitetsstøtten for akkurat-i-tid ble skrevet av Zoltan Herczeg og er ikke adressert i POSIX-innpakningen.

Fleksibel minnestyring

Bruken av systemstakken for backtracking kan være problematisk i PCRE1, og derfor ble denne funksjonen i implementeringen endret i PCRE2. Bunken brukes nå til dette formålet, og det totale beløpet kan begrenses. Problemet med stack overflow , som kom regelmessig med PCRE1, er ikke lenger et problem med PCRE2 fra utgivelse 10.30 (2017).

Konsekvent rømningsregler

I likhet med Perl har PCRE2 konsekvente regler for rømning: ethvert ikke-alfanumerisk tegn kan unnslippes for å bety bokstavelig verdi ved å sette et \(bakoverstrekk) foran tegnet. Ethvert alfanumerisk tegn som går foran en skråstrek, gir det vanligvis en spesiell betydning. I tilfelle sekvensen ikke er definert som spesiell, oppstår det en feil. Dette er forskjellig fra Perl, som bare gir en feil hvis den er i advarselsmodus (PCRE2 har ikke en advarselsmodus). I grunnleggende POSIX-regulære uttrykk slapp noen ganger tilbakeslagstrekk fra ikke-alfanumeriske tall (f.eks. \.), Og noen ganger introduserte de en spesiell funksjon (f.eks. \(\)).

Utvidede karakterklasser

Single-brev karakterklasser støttes i tillegg til de lengre POSIX navn. For eksempel \dsamsvarer et hvilket som helst siffer nøyaktig slik det [[:digit:]]ville være i POSIX regulære uttrykk.

Minimal matching (aka "ungreedy")

A ?kan plasseres etter en repetisjonsmåler for å indikere at den korteste kampen skal brukes. Standarden er å prøve den lengste kampen først og gå tilbake gjennom kortere kamper: f.eks. a.*?bVille matche "ab" i "ababab", hvor a.*bville matche hele strengen.

Unicode -tegnegenskaper

Unicode definerer flere egenskaper for hvert tegn. Mønstre i PCRE2 kan matche disse egenskapene: f.eks. Vil matche en streng som begynner med en "åpningstegn" og slutter med en "tett tegnsetting" som f.eks . Matching av visse "normale" metategn kan drives av Unicode -egenskaper når kompileringsalternativet PCRE2_UCP er angitt. Alternativet kan angis for et mønster ved å inkludere det i begynnelsen av mønsteret. Alternativet endrer oppførsel av følgende metategn: , , , , , , , , og noen av POSIX karakterklasser. For eksempel utvides settet med tegn som matches med (ordtegn) til å inkludere bokstaver og bokstaver med aksent som definert av Unicode -egenskaper. Slik matching er tregere enn det vanlige ( ASCII -bare) ikke -UCP -alternativet. Vær oppmerksom på at UCP -alternativet krever at biblioteket er bygget for å inkludere Unicode -støtte (dette er standard for PCRE2). Svært tidlige versjoner av PCRE1 støtter bare ASCII -kode. Senere ble UTF-8-støtte lagt til. Støtte for UTF-16 ble lagt til i versjon 8.30, og støtte for UTF-32 i versjon 8.32. PCRE2 har alltid støttet alle tre UTF -kodingene. \p{Ps}.*?\p{Pe}[abc](*UCP)\B\b\D\d\S\s\W\w\w

Matching med flere linjer

^og $kan bare matche i begynnelsen og slutten av en streng, eller ved begynnelsen og slutten av hver "linje" i strengen, avhengig av hvilke alternativer som er angitt.

Newline/linebreak alternativer

Når PCRE er kompilert, velges en standard for ny linje. Hvilken ny linje/linjeskift som i virkeligheten påvirker hvor PCRE oppdager ^begynnelsen og $enden på linjen (i fleretrådsmodus), samt hva som matcher punktum (uavhengig av flerlinjesmodus, med mindre punktall -alternativet (?s)er angitt). Det påvirker også PCRE -matchingsprosedyren (siden versjon 7.0): når et ikke -forankret mønster ikke samsvarer ved starten av en ny linjesekvens, går PCRE forbi hele newlinesekvensen før kampen prøver på nytt. Hvis alternativet for ny linje i virkeligheten inkluderer CRLF som et av de gyldige linjebruddene, hopper det ikke over \ni en CRLF hvis mønsteret inneholder spesifikke \reller \nreferanser (siden versjon 7.3). Siden versjon 8.10 \Nmatcher metakarakteren alltid et annet tegn enn linjeskifttegn. Den har samme oppførsel som .når dotall -alternativet aka (?s)ikke er i kraft.

Newline -alternativet kan endres med eksterne alternativer når PCRE kompileres og når det kjøres. Noen programmer som bruker PCRE gir brukerne muligheten til å bruke denne innstillingen via et eksternt alternativ. Så newline -alternativet kan også angis i begynnelsen av mønsteret ved å bruke ett av følgende:

  • (*LF)Newline er en linefeed -karakter. Tilsvarende linjebrudd kan matches med \n.
  • (*CR)Newline er en vognretur. Tilsvarende linjebrudd kan matches med \r.
  • (*CRLF)Newline/linebreak er en vognretur etterfulgt av en linefeed. Tilsvarende linjebrudd kan matches med \r\n.
  • (*ANYCRLF)Enhver av de ovennevnte som finnes i dataene vil utløse behandling av ny linje. Tilsvarende linjebrudd kan matches med eller med . Se nedenfor for konfigurasjon og alternativer angående hva som matcher backslash-R.(?:\r\n?|\n)\R
  • (*ANY) Noen av de ovennevnte pluss spesielle Unicode -linjebrudd.

Når den ikke er i UTF-8-modus, kan tilsvarende linjebrudd matches med eller . (?:\r\n?|\n|\x0B|\f|\x85)\R

I UTF-8-modus gjenkjennes to ekstra tegn som linjeskift med (*ANY):

  • LS (linjeseparator, U+2028),
  • PS (avsnittsseparator, U+2029).

I Windows, i ikke-Unicode-data, har noen av ANYlinjebruddstegnene andre betydninger.

\x85Kan for eksempel matche en horisontal ellipse, og hvis den oppstår mens den nye ANYlinjen er i kraft, vil det utløse behandling av ny linje.

Se nedenfor for konfigurasjon og alternativer angående hva som matcher backslash-R.

Backslash-R alternativer

Når PCRE er kompilert, velges en standard for det som samsvarer \R. Standarden kan enten være å matche linjebruddene som tilsvarer ANYCRLF eller de som tilsvarer ALLE. Standarden kan overstyres når det er nødvendig ved å inkludere (*BSR_UNICODE)eller (*BSR_ANYCRLF)i begynnelsen av mønsteret. Når du gir et (*BSR..)alternativ, kan du også tilby et alternativ, f.eks . Backslash-R-alternativene kan også endres med eksterne alternativer ved at programmet ringer PCRE2, når et mønster kompileres. (*newline)(*BSR_UNICODE)(*ANY)rest-of-pattern

Begynnelsen på mønsteralternativer

Linjebrytingsalternativer som (*LF)dokumentert ovenfor; backslash-R alternativer som (*BSR_ANYCRLF)dokumentert ovenfor; Alternativet Unicode Character Properties (*UCP)dokumentert ovenfor; (*UTF8)alternativet dokumentert som følger: Hvis PCRE2-biblioteket ditt har blitt kompilert med UTF- støtte, kan du angi (*UTF)alternativet i begynnelsen av et mønster i stedet for å angi et eksternt alternativ for å åpne UTF-8, UTF-16 eller UTF-32-modus.

Tilbakereferanser

Et mønster kan referere tilbake til resultatene fra en tidligere kamp. For eksempel, (a|b)c\1ville matche enten "aca" eller "bcb" og ville ikke matche, for eksempel "acb".

Navngitte undermønstre

Et delmønster (omgitt av parenteser, f.eks. (...)) Kan navngis ved å inkludere en ledning ?P<name>etter åpningsparentesen. Navngitte undermønstre er en funksjon som PCRE adopterte fra Python regulære uttrykk.

Denne funksjonen ble senere adoptert av Perl, så nå kan navngitte grupper også defineres ved hjelp av (?<name>...)eller (?'name'...), samt (?P<name>...). Navngitte grupper kan refereres til for eksempel: (?P=name)( Pythonsyntaks ) eller \k'name'(Perl -syntaks).


Subrutiner

Mens en referanse gir en mekanisme for å referere til den delen av motivet som tidligere har matchet et delmønster, gir en underprogram en mekanisme for å gjenbruke et underliggende tidligere definert delmønster. Undermønsterets alternativer, for eksempel sakens uavhengighet, er faste når delmønsteret er definert. (a.c)(?1)ville matche "aacabc" eller "abcadc", mens bruk av en backreference (a.c)\1ikke ville gjort det, selv om begge ville matche "aacaac" eller "abcabc". PCRE støtter også en ikke-Perl Oniguruma- konstruksjon for subrutiner. De er spesifisert ved hjelp av \g<subpat-number>eller \g<subpat-name>.

Atomisk gruppering

Atomisk gruppering er en måte å forhindre backtracking i et mønster. For eksempel a++bcvil matche så mange "a" er som mulig, og aldri sikkerhetskopiere for å prøve en mindre.

Se fremover og se bak-påstander

Påstand Se bak Se fremover
Positiv (? <= mønster ) (? = mønster )
Negativ (? <! mønster ) (? ! mønster )
Se-bak og se-frem-påstander
i Perl regulære uttrykk

Mønstre kan hevde at tidligere tekst eller påfølgende tekst inneholder et mønster uten å bruke samsvarende tekst (påstand om null bredde). For eksempel \w+(?=\t)matcher / / et ord etterfulgt av en fane , uten å inkludere selve fanen.

Innblikk-påstander kan ikke ha en usikker lengde, men (i motsetning til Perl) kan hver gren ha en annen fast lengde.

\Kkan brukes i et mønster for å tilbakestille starten på gjeldende hele kamp. Dette gir en fleksibel alternativ tilnærming til tilbakeblikk-påstander fordi den forkastede delen av kampen (delen som går før \K) ikke trenger å være fast i lengden.

Escape-sekvenser for påstander med null bredde

F.eks. \bFor å matche nullbredde "ordgrenser", lignende . (?<=\W)(?=\w)|(?<=\w)(?=\W)|^|$

Kommentarer

En kommentar begynner med (?#og slutter ved neste avsluttende parentes.

Rekursive mønstre

Et mønster kan referere til seg selv rekursivt eller til et hvilket som helst delmønster. For eksempel vil mønsteret matche enhver kombinasjon av balanserte parenteser og "a" s. \((a*|(?R))*\)

Generiske infomeldinger

PCRE -uttrykk kan bygge inn (?C''n''), hvor n er et tall. Dette vil ringe til en ekstern brukerdefinert funksjon via PCRE API og kan brukes til å legge inn vilkårlig kode i et mønster.

Forskjeller fra Perl

Forskjellene mellom PCRE2 og Perl (fra Perl 5.9.4) inkluderer, men er ikke begrenset til:

Fram til utgivelsen var 10.30 rekursive kamper atomiske i PCRE og ikke -atomiske i Perl

Dette betydde at det ville matche i Perl, men ikke i PCRE2 før utgivelsen 10.30. "<<!>!>!>><>>!>!>!>" =~ /^(<(?:[^<>]+|(?3)|(?1))*>)()(!>!>!>)$/

Verdien av en fangstbuffer som kommer fra ?kvantifisereren (match 1 eller 0 ganger) når den er nestet i en annen kvantifisert fangstbuffer, er forskjellig

I Perl vil det resultere i å inneholde "a" og inneholde , men i PCRE vil det resultere i å inneholde "b". "aba" =~ /^(a(b)?)+$/;$1$2undef$2

PCRE lar navngitte fangstbuffere få numeriske navn; Perl krever at navnet følger regelen for bareord

Dette betyr at det \g{}er entydig i Perl, men potensielt tvetydig i PCRE.

Dette er ikke lenger en forskjell siden PCRE 8.34 (utgitt 2013-12-15), som ikke lenger lar gruppenavn begynne med et siffer.

PCRE lar alternativer innenfor lookbehind være forskjellige lengder

Innen lookbehind-påstander krever både PCRE og Perl mønstre med fast lengde.

Det vil si at både PCRE og Perl ikke tillater mønstre med variabel lengde.

Perl krever imidlertid at alle alternative grener av en lookbehind -påstand skal ha samme lengde som hverandre, mens PCRE lar de alternative grenene ha forskjellige lengder fra hverandre så lenge hver gren fortsatt har en fast lengde.

PCRE støtter ikke visse "eksperimentelle" Perl -konstruksjoner

Såsom (??{...})(en tilbakeringing hvis retur blir vurdert som en del av mønsteret) eller (?{})konstruksjonen, selv om sistnevnte kan etterlignes ved hjelp av (?Cn).

Rekursjonskontrollverb lagt til i Perl 5.9.x -serien støttes heller ikke.

Støtte for eksperimentelle backtracking -kontrollverb (lagt til i Perl 5.10) er tilgjengelig i PCRE siden versjon 7.3.

De er (*FAIL), (*F), (*PRUNE), (*SKIP), (*THEN), (*COMMIT), og (*ACCEPT).

Perls tilsvarende bruk av argumenter med backtracking -kontrollverber støttes vanligvis ikke.

Merk imidlertid at siden versjon 8.10 støtter PCRE følgende verb med en spesifisert argument: (*MARK:markName), (*SKIP:markName), (*PRUNE:markName), og (*THEN:markName).

Siden versjon 10.32 PCRE2 har støttet (*ACCEPT:markName), (*FAIL:markName)og (*COMMIT:markName).

PCRE og Perl er litt forskjellige i sin toleranse overfor feil konstruksjoner

Perl tillater kvantifiseringer på (?!...)konstruksjonen, som er meningsløs, men ufarlig (om enn ineffektiv); PCRE produserer en feil i versjoner før 8.13.

PCRE har en hard grense for rekursjonsdybde, det har Perl ikke

Med standard bygger alternativer ikke på grunn av grensen, men Perl vil matche dette riktig. "bbbbXcXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" =~ /.X(.+)+X/

Perl bruker haugen for rekursjon og har ingen hard grense for rekursjonsdybde, mens PCRE2 har en standardgrense for kompileringstid som kan justeres opp eller ned av anropsprogrammet.

Med unntak av punktene ovenfor er PCRE i stand til å bestå testene i Perl- t/op/re_testsfilen, en av de viktigste syntaksnivå-regresjonstestene for Perls regulære uttrykksmotor.

Notater og referanser

Merknader

  1. ^ Kjerne -PCRE2 -biblioteket gir både samsvar og match og erstatt funksjonalitet.
  2. ^ Sikker på atdelen ikke er det? (dvs.som U+0085  ! = 0x85) Advarsel : Hvis mønsteretikke fungerte: eksperimentere med RegEx -implementeringens Unicode -innstillinger, eller prøv å erstatte med følgende: \x85\xC2\x85(?:\r\n?|\n|\x0B|\f|\xC2\x85)

    \xC2\x85
    • \x{0085}
    • \u0085

Referanser

  1. ^ Indeks over/pub/pcre/: https://ftp.pcre.org/pub/pcre/
  2. ^ Exim og PCRE: Hvordan gratis programvare kapret livet mitt (1999-12), av Philip Hazel , s. 7: https://www.ukuug.org/events/winter99/proc/PH.ps

    Hva med PCRE?

    • Skrevet sommeren 1997, plassert på ftp nettsted.
    • Folk fant den, og startet en postliste.
    • Det har skjedd en forbedring.
  3. ^
  4. ^ PCRE2 - Perl -kompatible regulære uttrykk (revidert API) (2020), av University of Cambridge : https://pcre.org/pcre2.txt
  5. ^ Forskjeller mellom PCRE2 og Perl (2019-07-13), av Philip Hazel : https://www.pcre.org/current/doc/html/pcre2compat.html
  6. ^ Sitat PCRE changelog ( https://www.pcre.org/original/changelog.txt ): "Perl lar ikke lenger gruppenavn begynne med sifre, så jeg har gjort denne endringen også i PCRE."
  7. ^ ChangeLog for PCRE2: https://www.pcre.org/changelog.txt

Se også

Eksterne linker