Voorbeelden van reguliere expressies van Perl. Metatekens in reguliere expressies. Syntaxis van reguliere expressies

Reguliere expressies van Perl

perl- Perl reguliere expressies
Deze tutorial beschrijft de syntaxis van reguliere expressies in Perl. Een beschrijving van hoe u reguliere expressies praktisch kunt gebruiken bij patroonvergelijkingsbewerkingen, evenals verschillende voorbeelden over dit onderwerp, kunt u vinden in de secties M// En S/// op de helppagina perlop.

BESCHRIJVING van reguliere expressies

Overeenkomende bewerkingen kunnen verschillende modifiers hebben, waaronder modifiers die verband houden met de interpretatie van de gebruikte reguliere expressies. Dit zijn de modificatoren:

Dit laatste wordt gewoonlijk de "/x modifier" genoemd, hoewel het betreffende scheidingsteken mogelijk geen schuine streep is. In feite kan elk van deze modifiers in een reguliere expressie worden ingebouwd met behulp van de nieuwe constructie (?...) . Zie hieronder.

De modificator zelf /X vereist iets meer details. Het zorgt ervoor dat de reguliere expressie-parser negeert witruimte tekens, niet ontsnapt door een backslash en geen onderdeel van een karakterklasse. Dit kan worden gebruikt om een ​​reguliere expressie op te delen in (iets) begrijpelijker delen. Symbool # wordt ook behandeld als het metateken voor het begin van het commentaar, net als in de rest van de Perl-code. Alles bij elkaar maken deze functies Perl 5 een veel beter leesbare taal. Zie voorbeeldcode voor het verwijderen van commentaar in een C-programma op de manpagina perlop.

Reguliere expressies

De patronen die worden gebruikt bij het matchen van patronen zijn reguliere expressies van het type dat wordt gebruikt in versie 8 van de bibliotheek regexp. (In feite zijn de overeenkomstige functies afgeleid (hoewel erg ver weg) van de vrij verkrijgbare versie 8-implementatie van Henry Spencer.) Zie sectie voor meer details. "Regelmatige expressies versie 8".

In het bijzonder het volgende metatekens hebben standaard, vertrouwd egrep, waarden:

Standaard is het symbool " ^ " komt gegarandeerd alleen overeen met het begin van de tekenreeks en het teken " $ " - alleen het einde van de regel (of de positie vóór de nieuwe regel aan het einde), en Perl maakt een aantal optimalisaties gebaseerd op de veronderstelling dat de buffer slechts één regel bevat. Ingebouwde regelfeeds komen niet overeen met metatekens " ^ " of " $ ". Het kan echter nodig zijn om de buffer als multiline te behandelen, zodat " ^ " kwam overeen met de positie na het nieuweregelteken in de buffer, en " $ " - posities vóór het newline-teken. Ten koste van een lichte toename van de overhead kan dit worden gedaan met behulp van een modifier /M in de patroonvergelijkingsoperator. (Hiervoor zijn oude programma's geïnstalleerd $* , maar deze praktijk is niet langer logisch in Perl 5.)

Om vervangingen van meerdere regels te vereenvoudigen, wordt de " . " komt nooit overeen met een newline-teken, tenzij er een modifier wordt gebruikt /S, wat Perl vertelt de buffer als een enkele regel te behandelen - zelfs als deze meerdere regels bevat. Wijziger /S annuleert ook de installatie $* , als de (mislukte) oude code wordt gebruikt, deze in een andere module instellen.

De volgende worden herkend standaard kwantoren:

(Als de accolade in een andere context voorkomt, wordt deze behandeld als een normaal teken.) De modifier " * "is gelijkwaardig {0,} , modificator " + " - {1,} , en de modificator " ? " - {0,1} . N En M moet gehele waarden hebben die niet groter zijn dan 65536.

Standaard is het gekwantificeerde subpatroon "hebzuchtig", d.w.z. het zal zoveel mogelijk exemplaren matchen, zodat de rest van het patroon kan worden gematcht. Alle standaardkwantificeerders zijn 'hebzuchtig' omdat worden vergeleken met het maximaal mogelijke aantal gebeurtenissen (vanaf een bepaalde locatie). Als u wilt matchen met een zo laag mogelijk aantal exemplaren, moet u " achter de kwantor opgeven ? ".

Bedenk wat er verandert niet de betekenis van de kwantoren, maar het ‘gewicht’, - waarmee ze vergeleken zullen worden kleinst mogelijke substring:

Omdat patronen worden behandeld als tekenreeksen tussen dubbele aanhalingstekens, volgende metakarakters zal ook werken:

\T tabel
\N lijnvoeding
\R vervoer retour
\F formulier feed
\A piep
\ e ontsnappen (onthoud trof)
\033 octaal karakter (denk aan PDP-11)
\x1B hexadecimaal teken
\C[ controle karakter
\l converteer het volgende teken naar kleine letters (onthoud vi)
\ u converteer het volgende teken naar hoofdletters (onthoud vi)
\L converteren naar kleine letters tot \E(herinneren vi)
\U converteren naar hoofdletters tot \E(herinneren vi)
\E einde van de zaakwijziging (onthoud vi)
\Q metakarakters maskeren regexp naar \E

Daarnaast, Perl definieert de volgende metatekens:

Houd er rekening mee dat \w komt overeen met een enkel alfanumeriek teken in plaats van met een heel woord. Om een ​​woord te matchen, moet je gebruiken \w+. Metakarakters \w, \W, \S, \S, \D En \D kan worden gebruikt bij het opgeven van tekenklassen (maar niet als een van de bereikgrenzen).

Perl definieert het volgende uitspraken met een lengte van nul (beweringen met nulbreedte):

Woordgrens ( \B) wordt gedefinieerd als een punt tussen twee karakters, aan één kant daarvan \w, en aan de andere kant - \W(in willekeurige volgorde), rekening houdend met de overeenkomende denkbeeldige begin- en eindtekens van de regel \W. (Binnen karakterklassen \B vertegenwoordigt een backspace, geen woordgrens.) Metatekens \A En \Z vergelijkbaar" ^ " En " $ ", maar wordt niet meerdere keren gematcht bij gebruik van de modifier /M, terwijl " ^ " En " $ " komt overeen met de grens van elke interne regel. Om een ​​overeenkomst met het daadwerkelijke einde van de regel op te geven, zonder het regelinvoerteken uit te sluiten, kunt u gebruiken \Z(?!\n).

Bij gebruik van beugelconstructie (...) , \<цифра> komt overeen <цифра> e subreeks. Buiten het patroon altijd vóór het nummer " $ "in plaats van" \ ". (Dossier \<цифра> kan in zeldzame gevallen buiten het huidige patroon vuren, maar er mag niet op worden vertrouwd. Zie hieronder.) Toepassingsgebied $ (en ook $` , $& En $" ) strekt zich uit tot het einde van het omsluitende blok of de omsluitende lijn die wordt geëvalueerd, of tot de volgende succesvolle patroonmatch, afhankelijk van wat zich het eerst voordoet. Als u haakjes wilt gebruiken om een ​​subpatroon (zoals een reeks alternatieven) te beperken zonder het als subpatroon te onthouden, geeft u ? na (.

U kunt een willekeurig aantal haakjes gebruiken. Als er meer dan 9 subtekenreeksen zijn, worden de variabelen $10 , $11 , ... verwijst naar de overeenkomstige subtekenreeks. In de sjabloon \10 , \11 enz. verwijzen naar reeds overeenkomende subtekenreeksen als er al zoveel subtekenreeksen waren vóór deze terugverwijzing. Anders (voor achterwaartse compatibiliteit) \10 valt samen met \010 , of een symbool van slachting, en \11 valt samen met \011 , een tabteken. En zo verder. (Sequenties uit \1 naar \9 worden altijd behandeld als backlinks.)

$+ geeft terug waarmee het laatste construct tussen haakjes is vergeleken. $& retourneert de gehele overeenkomende tekenreeks. (Eerder werd het hiervoor gebruikt $0 , maar wordt niet meer gebruikt.) $` retourneert alles wat vóór het begin van de overeenkomende tekenreeks komt. $" retourneert alles wat na de overeenkomende tekenreeks komt. Voorbeelden:

S/^([^ ]*) *([^ ]*)/$2 $1/; # swap # eerste twee woorden if (/Tijd: (..):(..):(..)/) ( $uren = $1; $minuten = $2; $seconden = $3; )

Merk op dat alle metatekens voorafgegaan door een backslash in Perl alfanumeriek zijn, b.v. \B, \w, \N. In tegenstelling tot sommige reguliere expressietalen gaat de backslash niet vooraf aan niet-alfanumerieke metatekens. Daarom zijn alle constructies van de vorm \\ , \(, \) , \< , \> , \{ of \} worden altijd geïnterpreteerd als letterlijke karakters en niet als metatekens. Dit maakt het gemakkelijk om aan een string te ontsnappen die u als patroon wilt gebruiken, maar waarvan u bang bent dat deze metatekens bevat. Escape alle niet-alfanumerieke tekens:

$patroon =~ s/(\W)/\\$1/g;

Je kunt hiervoor ook de ingebouwde functie gebruiken quotemeta(). Een nog eenvoudigere manier om metatekens rechtstreeks in de overeenkomende operator te escapen is als volgt:

/$niet geciteerd\Q$geciteerd\E$niet geciteerd/

Perl 5 definieert een consistente extensiesyntaxis voor reguliere expressies. Dit wordt gedaan met behulp van een paar haakjes met een vraagteken als eerste teken (dit was een syntaxisfout in Perl 4). Het teken na het vraagteken specificeert de uitbreidingsfunctie. Er worden verschillende extensies ondersteund:

(?#tekst)

Opmerking. De tekst wordt genegeerd. Als de schakelaar wordt gebruikt /X om opmaakruimten in te voegen, specificeert u gewoon # .

(?:regexp) Groepeert elementen op dezelfde manier als " () ", maar creëert geen backlinks zoals " () ". Daarom splitsen(/\b(?:a|b|c)\b/)

op dezelfde manier

Splitsen(/\b(a|b|c)\b/)

maar genereert geen extra velden.

(?=regexp) Een positieve vooruitblik van nul lengte. Bijvoorbeeld, /\w+(?=\t)/ komt overeen met een woord gevolgd door een tabteken, maar de tab is niet opgenomen $& .
(?!regexp) Een negatieve vooruitblik van nul lengte. Bijvoorbeeld, /foo(?!bar)/ komt overeen met elk voorkomen van " foe"dat volgt niet" bar". Houd er echter rekening mee dat vooruitkijken en vooruitkijken NIET hetzelfde zijn. Je kunt deze constructie niet gebruiken om terug te kijken: /(?!foo)bar/ zal geen vermelding vinden " bar"wat niet eerder komt" foe". Dit gebeurt omdat (?!foe) betekent dat er geen verdere lijn mag zijn " foe"- en ze gaat niet, ze gaat" bar", Daarom" foobar" komt overeen met dit patroon. U moet zoiets specificeren als /(?foo)...bar/. "Vind ik leuk" - omdat eerder " bar" mag niet uit drie tekens bestaan. Deze zaak kan als volgt worden behandeld: /(?:(?!foo)...|^..?)bar/. Soms is het gemakkelijker om te schrijven: if (/foo/ && $` =~ /bar$/)
(?imsx) Een of meer ingebouwde patroonaanpassingsmodificatoren. Dit is vooral handig voor patronen die in een aparte tabel zijn gedefinieerd, waarbij sommige hoofdlettergevoelig moeten zijn en andere niet. Voor hoofdlettergevoelige tekens schakelt u eenvoudigweg in (?i) vóór het sjabloon. Bijvoorbeeld: $pattern = "foobar";
if (/$pattern/i) # flexibelere manier: $pattern = "(?i)foobar";

Het vraagteken hiervoor en het nieuwe minimale matching-construct werd gekozen omdat 1) een vraagteken zelden werd gezien in eerdere reguliere expressies en 2) als je een vraagteken ziet, je moet stoppen en jezelf moet "vragen" wat er werkelijk aan de hand is . Dit is psychologie...

Reguliere expressies: teruggaan

De fundamentele eigenschap van het matchen van reguliere expressies houdt verband met een concept dat backtracking wordt genoemd en dat (indien nodig) wordt gebruikt door alle kwantoren van reguliere expressies, namelijk * , *? , + , +? , (n,m) En (n,m)?.

Wil een reguliere expressie overeenkomen met een patroon, dan moet deze als geheel overeenkomen, en niet slechts gedeeltelijk. Dus als het begin van een patroon dat een kwantificator bevat met succes wordt gematcht, zodat de rest van het patroon niet wordt gematcht, gaat de matching-engine terug en berekent het begingedeelte opnieuw – vandaar de naam backtracking.

Hier is een voorbeeld van een backtracking-zoekopdracht: Stel dat u het woord wilt vinden dat volgt op ' foe"in de rij" Er staat eten op de tafel.":

$_ = "Eten staat op tafel."; if (/\b(foo)\s+(\w+)/i) ( print "$2 volgt $1.\n"; )

Bij het uitvoeren van een overeenkomst op het eerste deel van de reguliere expressie ( \b(foe)) er is een mogelijke match direct aan het begin van de regel, terwijl deze binnen is $1 de waarde " wordt geplaatst Foo". Maar zodra de matching-engine dat ziet na het opslaan $1 waarden" Foo" er is geen spatie, hij zal zijn fout beseffen en opnieuw beginnen bij het volgende teken na de mislukte match van an. Deze keer gaat hij door tot de volgende gebeurtenis " foe". De gehele reguliere expressie als geheel is nu gekoppeld en zal het verwachte resultaat opleveren," tabel volgt foo.".

Soms kan minimale matching erg nuttig zijn. Stel dat je alles moet vinden wat tussen de regels staat " foe" En " bar". Je kunt meteen iets schrijven als:

$_ = "Het eten staat onder de bar in de schuur."; if (/foo(.*)bar/) ( print "kreeg<$1>\N"; )

Wat, misschien onverwacht, het volgende oplevert:

Gekregen

Dit gebeurde omdat de template .* was hebzuchtig, dus je kreeg alles van de eerste " foe"tot het laatst" bar". In dit geval is het efficiënter om een ​​minimale match te gebruiken, zodat je de tekst tussen " foe"en de allereerste gebeurtenis" bar"na hem.

If (/foo(.*?)bar/) ( print "kreeg<$1>\n" ) gekregen

Hier is nog een voorbeeld: stel dat u het getal aan het einde van een reeks wilt vinden en het vorige overeenkomende deel wilt behouden. Je schrijft het volgende:

$_ = "Ik heb 2 nummers: 53147";
if (/(.*)(\d*)/) ( #Error! print "Begin is<$1>, nummer is<$2>.\N"; )

Dit werkt helemaal niet omdat de template .* was hebzuchtig en verslond de hele rij. Sinds \D* kan overeenkomen met de lege tekenreeks, wordt de gehele reguliere expressie als geheel met succes gematcht.

Begin is , nummer is<>.

Hier zijn nog een paar opties, waarvan de meeste niet werken:

$_ = "Ik heb 2 nummers: 53147"; @pats = qw( (.*)(\d*) (.*)(\d+) (.*?)(\d*) (.*?)(\d+) (.*)(\d+)$ (.*?)(\d+)$ (.*)\b(\d+)$ (.*\D)(\d+)$ ); voor $pat (@pats) ( printf "%-12s ", $pat; if ($pat/) ( print "<$1> <$2>\n"; ) else ( print "FAIL\n"; ) ) Het resultaat zal zijn:
(.*)(\D*) <>(.*)(\d+) <7>(.*?)(\D*)<> <>(.*?)(\d+) <2>(.*)(\d+)$ <7>(.*?)(\d+)$ <53147>(.*)\b(\d+)$ <53147>(.*\D)(\d+)$ <53147>

Zoals je kunt zien, kan dit allemaal een beetje lastig zijn. Het is belangrijk om te begrijpen dat een reguliere expressie eenvoudigweg een reeks instructies is die een succesvol resultaat bepalen. Kan 0, 1 of meer zijn op verschillende manieren voldoen aan de definitie op een specifieke regel. En als er meerdere succesvolle matches zijn, moet u de backtracking begrijpen om te weten welke succesvolle match zal worden verkregen.

Bij het gebruik van vooruitkijk- en ontkenningen kan de situatie nog ingewikkelder worden. Stel dat u een reeks tekens wilt vinden, behalve cijfers, die niet worden gevolgd door ' 123 ". Je kunt proberen het zo te schrijven

$_ = "ABC123"; if (/^\D*(?!123)/) ( # Fout! print "Ja, geen 123 in $_\n"; )

Maar er zal geen resultaat zijn; tenminste niet wat je had verwacht. Er wordt beweerd dat die er niet is 123 . Hier is een duidelijker beeld van waarom, in tegenstelling tot wat vaak werd verwacht, de vergelijking plaatsvond:

$x = "ABC123"; $y = "ABC445" ; print "1: kreeg $1\n" als $x =~ /^(ABC)(?!123)/ ; print "2: kreeg $1\n" als $y =~ /^(ABC)(?!123)/ ; print "3: kreeg $1\n" als $x =~ /^(\D*)(?!123)/ ; print "4: kreeg $1\n" als $y =~ /^(\D*)(?!123)/ ;

Zal worden uitgegeven

2: kreeg ABC 3: kreeg AB 4: kreeg ABC

Je zou verwachten dat test 3 mislukt, omdat het een meer generieke versie van 1 lijkt te zijn. Het belangrijke verschil tussen de twee is dat test 3 een kwantor bevat (\D*) en kan daarom backtracking gebruiken, terwijl controle 1 dat niet kan. Wat je eigenlijk vraagt ​​is: ‘Is het waar dat dat in het begin zo was? $x, na 0 of meer niet-cijfers, komt er iets anders dan 123 ? Als het matchingmechanisme dit toelaat \D* uitbreiden naar " abc", zal niet het hele patroon overeenkomen. De zoekmachine zal in eerste instantie overeenkomen \D* Met " abc". Dan zal ze proberen te matchen (?!123) C" 123 ", wat natuurlijk onmogelijk is. Maar aangezien de kwantificator in de reguliere expressie wordt gebruikt (\D*), kan de zoekmachine teruggaan en naar een andere overeenkomst zoeken in de hoop een overeenkomst voor de gehele reguliere expressie te vinden.

Omdat patroonmatching zo gewenst is door de zoekmachine, gebruikt deze nu standaard rendement en probeer het opnieuw regexp(backoff-and-retry) en staat deze tijd toe \D* alleen uitbreiden naar " AB"Nu komt er echt iets na" AB", wat niet samenvalt met " 123 ". Dit " C123", wat zeer bevredigend is.

Je kunt hiermee omgaan door bevestiging en ontkenning samen te gebruiken. Dat zullen we na het eerste deel zeggen $1 er zou een nummer moeten zijn, maar er zou iets anders moeten zijn dan " 123 ". Onthoud dat lookaheads uitdrukkingen met een lengte van nul zijn - de match voert alleen een test uit, maar neemt geen deel van de reeks op. Na dergelijke wijzigingen wordt het gewenste resultaat verkregen; d.w.z. in geval 5 - mislukking, en in geval 6 - succes :

Print "5: kreeg $1\n" if $x =~ /^(\D*)(?=\d)(?!123)/ ; print "6: kreeg $1\n" if $y =~ /^(\D*)(?=\d)(?!123)/ ; 6: Ik heb ABC

Met andere woorden: twee uitspraken met een lengte van nul(nulbreedte-beweringen) op een rij werken alsof hun conjunctie wordt getest, net als bij alle ingebouwde beweringen: patroon /^$/ komt alleen overeen als u zich tegelijkertijd aan het begin van de regel EN aan het einde van de regel bevindt. De diepere reden hiervoor is dat aangrenzende expressies in reguliere expressies altijd AND betekenen, behalve wanneer expliciet OR wordt aangegeven met behulp van een pipe. /ab/ betekent vergelijken" A"En (dan) matchen" B", hoewel er in verschillende posities vergelijkingspogingen worden gedaan, omdat" A" is een verklaring die niet lengte nul heeft, maar lengte één.

Eén waarschuwing: bijzonder complexe reguliere expressies kunnen een exponentiële matchingtijd vereisen vanwege het enorme aantal mogelijke opties matching bij backtracking-zoekopdrachten. Het duurt bijvoorbeeld erg lang voordat het volgende patroon overeenkomt

/((een(0,5))(0,5))(0,5)/

En als je gebruikt * In plaats van het aantal gebeurtenissen te beperken van 0 tot 5, loopt de wedstrijd voor onbepaalde tijd - of totdat de stapelruimte is uitgeput.

Reguliere expressies versie 8

Als u niet bekend bent met de "standaard" bibliotheekfuncties regexp versie 8, hier zijn de patroonvergelijkingsregels die hierboven niet zijn beschreven.

Elk afzonderlijk teken komt overeen met zichzelf, tenzij het een metateken is met een speciale betekenis die hier of hierboven wordt beschreven. Van tekens die normaal gesproken als metatekens fungeren, kan worden geëist dat ze letterlijk worden geïnterpreteerd door ze te laten voorafgaan door ' \ " (Bijvoorbeeld, " \. "wedstrijden" . ", geen enkel karakter; " \\ "wedstrijden" \ "). De reeks tekens komt overeen met dezelfde reeks tekens in de doelreeks, dus het patroon vervagen komt overeen met " vervagen" in de doellijn.

U kunt een tekenklasse opgeven door een lijst met tekens tussen vierkante haakjes te plaatsen die overeenkomen met elk van de tekens in de lijst. Als het eerste teken na " [ " - "^ ", de klasse komt overeen met elk teken dat niet in de lijst is gespecificeerd. In de lijst komt het teken " - " wordt gebruikt om een ​​bereik aan te geven, dus a-z vertegenwoordigt alle tekens van " A"voor" z", inclusief.

Tekens kunnen worden gespecificeerd met behulp van een syntaxis van metatekens, vergelijkbaar met die in C: " \N" komt overeen met een nieuwe regel, " \T" - tabbladen, " \R" - regelretour, " \F" - formulierfeed, enz. Over het algemeen geldt \nnn, Waar nnn- is een reeks octale cijfers, komt overeen met een teken waarvan de ASCII-codewaarde is - nnn. Insgelijks, \xnn, Waar n- dit zijn hexadecimale cijfers, komt overeen met een teken waarvan de ASCII-codewaarde is - n. Uitdrukking \cx komt overeen ASCII-teken controle-x. Tenslotte het metakarakter " . " komt overeen met elk teken behalve " \N"(tenzij gebruikt /S).

U kunt een reeks alternatieven voor een sjabloon opgeven, gescheiden door het metateken " | ", Dus vergoeding|fie|vijand komt overeen met een van de subtekenreeksen " tarief", "fie" of " vijand" in de doelreeks (hetzelfde als f(e|i|o)e). Merk op dat het eerste alternatief alles omvat vanaf de laatste patroonscheidingsteken (" (", "[ " of vanaf het begin van het patroon) tot het eerste teken " | ", en het laatste alternatief omvat alles van laatste teken "| " naar het volgende patroonscheidingsteken. Daarom staan ​​alternatieven meestal tussen haakjes om er zeker van te zijn dat er geen twijfel bestaat waar ze beginnen en eindigen. Houd er echter rekening mee dat tussen vierkante haakjes " | " wordt geïnterpreteerd als letterlijk, dus als je schrijft , de vergelijking zal alleen plaatsvinden met .

Binnen een sjabloon kunt u subsjablonen markeren (door ze tussen haakjes te plaatsen) voor verdere referentie, en u kunt teruglinken naar N e subpatroon later met behulp van een metakarakter \N. Subpatronen worden van links naar rechts genummerd met behulp van haakjes. Houd er rekening mee dat de terugverwijzing overeenkomt met wat het subpatroon in de rij in kwestie overeenkomt, en niet met de regels die dat subpatroon definiëren. Dat is waarom (0|0x)\d*\s\1\d* komt overeen met " 0x1234 0x4321"maar niet met" 0x1234 01234"omdat subpatroon 1 daadwerkelijk overeenkwam" 0x"Hoewel de regel 0|0x kan mogelijk overeenkomen met de eerste 0 in het tweede getal.

WAARSCHUWING over \1 en $1

Sommige mensen zijn te gewend om dingen te schrijven zoals

$patroon =~ s/(\W)/\\\1/g;

De wortels van deze gewoonte gaan terug naar de rechterkant van de vervangingsoperator in sed, maar het is een slechte gewoonte. Het punt is dat vanuit het perspectief van Perl rechterkant S/// is een string tussen dubbele aanhalingstekens. \1 V reguliere lijn tussen dubbele aanhalingstekens betekent controle-A. De normale Unix-waarde \1 wordt opgeslagen S///. Als u er echter een gewoonte van maakt om het op deze manier te doen, zult u problemen ondervinden bij het toevoegen van de modifier /e.

S/(\d+)/ \1 + 1 /bijvoorbeeld; of als u s/(\d+)/\1000/;

Deze dubbelzinnigheid kan niet worden vermeden door te schrijven \{1}000 , maar het is mogelijk als je schrijft ${1}000 . Het is alleen zo dat de interpolatiebewerking niet mag worden verward met de bewerking voor het matchen van terugverwijzingen. Natuurlijk hebben ze verschillende betekenissen aan de linkerkant van de operator S///.

In dit hoofdstuk wordt de syntaxis van reguliere expressies beschreven. Het meest voorkomende gebruik ervan in Perl is in zoek- en vervangoperatoren zoals S//, M/, connectieve operators =~ of != enz. In de regel hebben al deze operators vergelijkbare opties, zoals:

Normaal gesproken worden al deze opties aangeduid als "/x". Ze kunnen zelfs in sjablonen worden gebruikt met behulp van nieuw ontwerp (?...)

Reguliere expressies of patronen zijn hetzelfde als regexp-procedures in Unix. Expressies en syntaxis zijn ontleend aan de vrij verspreide V8-procedures van Henry Spencer, waar ze in detail worden beschreven.

De sjablonen gebruiken de volgende metatekens (tekens die groepen andere tekens aanduiden), vaak de egrep-standaard genoemd:

Metatekens hebben modificatoren (geschreven na het metateken):

In alle andere gevallen worden accolades beschouwd als gewone (reguliere) tekens. Dus "*" is gelijk aan (0,) , "+" is (1,) en "?" - (0,1). n en m kunnen niet groter zijn dan 65536.

Standaard zijn metatekens hebzuchtig. De match wordt zo vaak mogelijk gepropageerd, zonder rekening te houden met het effect van daaropvolgende metatekens. Als je "hun eetlust wilt verminderen", gebruik dan het "?"-symbool. Dit verandert niets aan de betekenis van de metatekens, het vermindert alleen de verspreiding. Dus:

Sjablonen werken op dezelfde manier als dubbele aanhalingstekens, zodat u `\` - symbolen (backslash-symbolen) erin kunt gebruiken:

\T - tabbladteken
\N - nieuwe lijn
\R - vervoersoverdracht
\A - formaatvertaling
\v - verticale tabellering
\A - telefoongesprek
\ e - ontsnappen
\033 - octale symboolnotatie
\x1A - hexadecimaal
\C[ - controlesymbool
\l - kleine letter volgend teken
\ u - hoofdletters -//-
\L - alle tekens zijn kleine letters tot en met \E
\U - in het bovenste -//-
\E - registerwijzigingsbegrenzer
\Q - annuleer actie als metakarakter

Bovendien zijn de volgende metatekens aan Perl toegevoegd:

Merk op dat dit allemaal "één" teken is. Gebruik modifiers om de volgorde aan te geven. Dus:

Daarnaast zijn er denkbeeldige metatekens. Het aanduiden van niet-bestaande symbolen op de plaats waar de waarde verandert. Zoals:

Een woordgrens (\b) is een denkbeeldig punt tussen de tekens \w en \W. Binnen een tekenklasse vertegenwoordigt "\b" het backspace-teken. Metakarakters \A En \Z- “^” en “$” zijn vergelijkbaar, maar als begin van de lijn"^" en regeleinde "$" fungeren dan voor elke regel in een reeks met meerdere regels \A En \Z geven het begin en einde aan van een volledige reeks met meerdere regels.

Als binnen het patroon groepering (haakjes) wordt gebruikt, wordt het substringnummer van de groep aangeduid als "\digit". Merk op dat deze groepen, volgens het patroon binnen een expressie of blok, worden aangeduid als "$digit". Daarnaast zijn er aanvullende variabelen:

Voorbeeld:

$s = "Eén 1 twee 2 en drie 3"; if ($s =~ /(\d+)\D+(\d+)/) ( print "$1\n"; # Resultaat "1" print "$2\n"; # "2" print "$+\n" ; # "2" print "$&\n"; # "1 twee 2" print "$`\n" # "Eén " print "$"\n"; # " en drie 3" )

Perl versie 5 bevat aanvullende sjabloonconstructies:

Voorbeeld:

$s = "1+2-3*4"; if ($s =~ /(\d)(?=-)/) # Zoek het getal gevolgd door "-" ( print "$1\n"; # Resultaat "2" ) else ( print "zoekfout\n" ;) (?!patroon) - “vooruitkijkend” naar de ontkenning.

Voorbeeld:

$s = "1+2-3*4"; if ($s =~ /(\d)(?!\+)/) # Zoek een cijfer dat niet wordt gevolgd door "+" ( print "$1\n"; # Resultaat "2" ) else ( print "search fout\ n";)

(?ismx) - “interne” modificatoren. Het is handig om te gebruiken in sjablonen, waarbij u bijvoorbeeld een modifier in de sjabloon moet opgeven.

Regels voor reguliere expressies. (regex)

  1. Elk karakter vertegenwoordigt zichzelf, tenzij het een metakarakter is. Als u het effect van een metateken wilt annuleren, plaatst u er "\" voor.
  2. Tekenreeks geeft een reeks van deze tekens aan.
  3. De reeks mogelijke tekens (klasse) staat tussen vierkante haakjes "", dit betekent dat een van de tussen haakjes gespecificeerde tekens op deze plaats kan verschijnen. Als het eerste teken tussen haakjes “^” is, kan geen van de opgegeven tekens op dit punt in de uitdrukking voorkomen. Binnen een klasse kunt u het symbool "-" gebruiken om een ​​reeks tekens aan te duiden. A-z is bijvoorbeeld een van de kleine letters van het Latijnse alfabet, 0-9 is een getal, enz.
  4. Alle tekens, inclusief speciale, kunnen worden aangegeven met "\", zoals in de C-taal.
  5. Alternatieve reeksen worden gescheiden door "|" Merk op dat dit tussen de vierkante haakjes een normaal symbool is.
  6. Binnen een reguliere expressie kunt u "subpatronen" specificeren door ze tussen haakjes te plaatsen en ernaar te verwijzen als "\nummer". Het eerste haakje wordt aangeduid met "\1".
  1. Vervang meerdere spaties en niet-tekstuele tekens door enkele spaties:

    $text = "Hier is de tekst."
    $tekst =~ tr[\000-\040\177\377][\040]s;
    print $tekst;
    Hier is de tekst.

  2. Snijd dubbel, drievoudig, enz. brieven:

    $text = "Hier is de texxxxxxt.";
    $tekst =~ tr/a-zA-Z/s;
    print $tekst;
    Hier is de tekst.

  3. Bereken het aantal niet-lettertekens opnieuw:

    $xcount=($text =~ tr/A-Za-z//c);

  4. Wis het achtste bit met tekens, verwijder niet-tekstuele tekens:

    $tekst =- tr(\200-\377)(\000-\l77);
    $tekst =~ tr[\000-\037\177]d;

  5. Vervang niet-tekstuele en 8-bits tekens door een enkele spatie:

    $text =~ tr/\021-\176/ /cs;

Zoek naar afzonderlijke woorden

Om een ​​woord te markeren, kunt u het metateken \S gebruiken om tekens die geen witruimte bevatten te matchen:

$text = "Nu is het tijd.";
$tekst =- /(\S+)/;
afdrukken;
Nu

Het metateken \S komt echter ook overeen met tekens die doorgaans niet voor ID's worden gebruikt. Om woorden te selecteren die uit Latijnse letters, cijfers en onderstrepingstekens bestaan, moet u het metateken \w gebruiken:

$text = "Nu is het tijd.";
$tekst =~ /(\w+)/;
afdrukken;
Nu

Als u alleen Latijnse letters in de zoekopdracht wilt opnemen, moet u een tekenklasse gebruiken:

$text = "Nu is het tijd.";
$tekst =~ /(+)/;
afdrukken;
Nu

Meer veilige methode is om denkbeeldige woordgrenstekens in het patroon op te nemen:

$text = "Hoe is de tijd.";
$tekst=~/\b(+)\b/;
afdrukken;
Nu

Ga naar het begin van de regel

Het begin van een regel komt overeen met een metateken (denkbeeldig teken) ^ . Om het patroon naar het begin van de regel te laten gaan, moet u dit teken aan het begin van de reguliere expressie instellen. Zo kun je bijvoorbeeld controleren of de tekst niet met een punt begint:

$line = ".Hallo!";
als($regel=~m/^\./)(
print "Mag een zin niet beginnen met een punt!\n";
}
Je mag een zin niet beginnen met een punt!

Om te voorkomen dat de in het patroon gespecificeerde periode als een metateken zou worden geïnterpreteerd, was het nodig om deze vooraf te laten gaan door een backslash.

Ga naar het einde van de regel

Om een ​​patroon aan het einde van een string te verankeren, wordt het metateken (een denkbeeldig teken) $ gebruikt. In ons voorbeeld gebruiken we patroonbinding aan het begin en einde van de regel om ervoor te zorgen dat de gebruiker alleen het woord "exit" heeft ingevoerd:

Terwijl(<>){
if(m/"exlt$/) (afsluiten;)
}

Cijfers zoeken

$test = "Hallo!";
als($tekst =~ /\D/)(
print "Het is geen getal.\n";
}
Het is geen getal.

Hetzelfde kan worden gedaan met behulp van het metateken \d:

$tekst = "333";
als($tekst =~ /^\d+$/)(
print "Het is een getal.\n";
}
Het is een getal.

U kunt eisen dat het nummer een bekend formaat volgt. Dat wil zeggen dat een getal een decimale punt kan bevatten, voorafgegaan door ten minste één cijfer en mogelijk enkele cijfers erna:

$text= "3.1415926";
if($text =~ /^(\d+\.\d*|\d+)$/)(
print "Het is een getal.\n";
}
Het is een getal.

Bovendien kunt u bij het controleren rekening houden met het feit dat het getal kan worden voorafgegaan door een plus of een min (of een lege spatie):

$tekst = "-2.7182";
if ($tekst =~ /^([+-]*\d+)(\.\d*|)$/) (
print "Het is een getal.\n";

Omdat de plus een metateken is, moet deze worden beveiligd met een backslash. Binnen vierkante haakjes, dat wil zeggen een tekenklasse, kan het echter geen kwantificator zijn. Het minteken binnen een tekenklasse fungeert doorgaans als bereikoperator en moet daarom worden geëscaped met een backslash. Aan het begin of einde van het patroon kan het echter op geen enkele manier een bereik aangeven, en daarom is de backslash optioneel. Ten slotte vereist een strengere test dat het teken, indien aanwezig, slechts één teken is:

$tekst = "+0,142857142857142857";
als ($tekst =~ /^(+|-|)\d+(\.\d*\)$/) (
print "Het is een getal.\n";
}
Het is een getal.

Alternatieve patronen, indien aanwezig, worden van links naar rechts gecontroleerd. Het zoeken naar opties eindigt zodra er een match is gevonden tussen de tekst en het sjabloon. Daarom zou de volgorde van alternatieven in het patroon (\.\d*|) bijvoorbeeld van cruciaal belang kunnen worden als de end-of-line-binding er niet was. Ten slotte kunt u als volgt controleren of tekst een hexadecimaal getal is, zonder teken of andere attributen:

$text = "1AO";
tenzij (ftext =~ m/^+$/) (
print "Het is geen hexadecimaal getal,\n";
}

ID-verificatie

Je kunt het metateken \w gebruiken om te controleren of tekst alleen uit letters, cijfers en onderstrepingstekens bestaat (dit zijn wat perl woordtekens noemt):

$tekst=”abc”;
als($tekst=~/^\w+$/)(
print "Alleen woordtekens gevonden.\n";
}
Er zijn alleen woordtekens gevonden.

Als je er echter zeker van wilt zijn dat de tekst Latijnse letters bevat en geen cijfers of onderstrepingstekens, zul je een ander patroon moeten gebruiken:

$tekst = "abc";
if($text=~ /^+$/) ( print "Alleen lettertekens gevonden.\n"; )
Qnly lettertekens gevonden.

Om ten slotte te controleren of de tekst een identificatie is, dat wil zeggen dat deze begint met een letter en letters, cijfers en onderstrepingstekens bevat, kunt u de opdracht gebruiken:

$tekst = "X125c";
als($tekst=~ /^\w+$/) (
print "Dit is een identificatie.\n";
}
Dit is een identificatie.

Hoe u meerdere overeenkomsten kunt vinden

U kunt de g-modifier gebruiken om meerdere exemplaren van een patroon te matchen. Het volgende voorbeeld, dat we eerder zagen, gebruikt het commando m/.../ met de g-modifier om alle exemplaren van de letter x in de tekst te vinden:

$text="Hier is texxxxxt";
while($text=~m/x/g) (
print "Nog een x gevonden.\n";
}
Nog een x gevonden.
Nog een x gevonden.
Nog een x gevonden.
Nog een x gevonden.
Nog een x gevonden.

De g-modifier maakt de zoekopdracht globaal. In een gegeven (scalaire) context onthoudt perl waar het wanneer op de lijn stopte vorige zoekopdracht. De volgende zoekopdracht gaat verder vanaf het uitgestelde punt. Zonder de g-modifier zal het commando m/.../ koppig de eerste keer dat de letter x voorkomt vinden, en de lus zal voor onbepaalde tijd doorgaan.

In tegenstelling tot het commando m/.../ wordt het commando s/.../.../ met de modificator g uitgevoerd mondiale vervanging tegelijkertijd, alsof het al een ingebouwde zoeklus heeft, zoals die hierboven. In het volgende voorbeeld worden alle exemplaren van x in één keer vervangen door z:

$text = "Hier is texxxxt.";
$tekst =~ s/x/z/g;
print $tekst;
Hier is tezzzzt.

Zonder de g-modifier zal het commando s/.../.../ alleen de eerste letter x vervangen. Het commando s/.../.../ retourneert het aantal uitgevoerde vervangingen, wat handig kan zijn:

$text= "Hier is texxxxt.";
afdrukken (tekst =~ s/x/z/g)
5

Hoofdletterongevoelige overeenkomsten zoeken

U kunt de i-modifier gebruiken om de zoekopdracht ongevoelig te maken voor het verschil tussen hoofdletters en kleine letters. In het volgende voorbeeld herhaalt het programma de door de gebruiker ingevoerde tekst op het scherm totdat Q of q (afkorting van QUIT of quit) wordt ingevoerd, waarna het programma wordt afgesloten:

Terwijl(<>) {
kauwen;
tenzij (/^q$/i)(print
) anders (
Uitgang;
}
}

Selectie van subtekenreeksen

Om de gevonden subtekenreeks van tekst te verkrijgen, kunt u haakjes in de hoofdtekst van de sjabloon gebruiken. Als dit handiger is, kunt u ook de ingebouwde substr-functie gebruiken. In het volgende voorbeeld knippen we het type product dat we nodig hebben uit een tekstreeks:

$record = "Productnummer:12345
Producttype: printer
Productprijs: 5";
if($record=~/Producttype:\s*(+)/i)(
print "Het producttype is^.\n";
}
Het producttype is printer.

Functies oproepen en uitdrukkingen evalueren bij het vervangen van tekst

Door de e-modifier te gebruiken voor de opdracht s/.../.../ geeft u aan dat de rechteroperand (dat wil zeggen: de tekst die wordt vervangen) de perl-expressie is die moet worden geëvalueerd. U kunt bijvoorbeeld de in perl ingebouwde functie uc (hoofdletters) gebruiken om alle kleine letters van woorden in een string te vervangen door hoofdletters:

$text = "Nu is het tijd.";
$text=~ s/(\w+)/uc()/ge;
print $tekst;
NU IS DE TIJD.

In plaats van de uc($l)-functie kunt u willekeurige code plaatsen, inclusief programma-aanroepen.

Het vinden van de zoveelste match

De g-modifier wordt gebruikt om alle voorkomende gevallen van een bepaald patroon te doorlopen. Maar wat moet u doen als u een heel specifiek toevalspunt met de sjabloon nodig heeft, bijvoorbeeld de tweede of derde? Exploitant terwijl lus in combinatie met haakjes die het gewenste patroon benadrukken, helpt u:

$text = "Naam:Anne Nanie:Burkart Naam:Glaire Naam: Dan";
while ($text =~ /Naam: \s*(\w+)/g) (
+$overeenkomst;
print "Matchnummer $match is .\n";
}

Match nummer 1 is Anne
Match nummer 2 is Burkart
Match nummer 3 is Claire
Match nummer 4 is Dan

Dit voorbeeld kan worden herschreven met behulp van voor lus:

$text = "Naam:Anne Naam:Burkart Naam:Ciaire Naam:Dan";
voor ($overeenkomst = 0;
$text =~ /Naam:\s*(\w+)/g;
print "Matchnummer $(\match) is .\n")
{}
Match nr. 1 Is Anne
Match nummer 2 is Burkart
Match nummer 3 is Claire
Match nummer 4 is Dan

Als u de gewenste match niet op nummer, maar op inhoud (bijvoorbeeld op basis van de eerste letter van de gebruikersnaam) moet bepalen, kunt u in plaats van de $match-teller de inhoud analyseren van een variabele die bij elke match wordt bijgewerkt. wedstrijd gevonden. Wanneer u de tweede of derde teksttekst wilt vervangen in plaats van deze te zoeken, kunt u hetzelfde schema toepassen, waarbij u als hoofdtekst van de lus een perl-expressie gebruikt die wordt aangeroepen om de vervangende tekenreeks te evalueren:

$text = "Naam:Anne Naam:Burkart Naam:Claire Naam:Dan";
$overeenkomst =0;
$text =~ s/(Naam:\s*(\w+))/ # perl-code begint
if (+$match == 2) (# # verhogingsteller
"Naam:John ()" # retourneert nieuwe waarde
) else ( )# behoudt de oude waarde
/gex;
print $tekst;
Naam:Anne Naam:John (Burkart) Naam:ClaireNaam:Dan

Tijdens een globale zoekactie wordt voor elke gevonden overeenkomst de expressie geëvalueerd die is opgegeven als de tweede operand. Bij de berekening ervan wordt de tellerwaarde verhoogd en afhankelijk daarvan wordt de oude tekstwaarde of de nieuwe vervangen als vervanging. Met de x-modifier kunt u opmerkingen toevoegen aan een sjabloonveld, waardoor de code transparanter wordt. Houd er rekening mee dat we het hele patroon tussen haakjes moesten plaatsen om de waarde van de gevonden tekst te achterhalen en deze volledig te vervangen.

Hoe de "hebzucht" van kwantoren te beperken

Standaard gedragen kwantoren zich als hebzuchtige objecten. Beginnend bij de huidige zoekpositie pakken ze de langste tekenreeks die de reguliere expressie kan matchen vóór de kwantor. Het backtracking-algoritme van Perl kan de eetlust van kwantoren beperken door terug te gaan en de lengte van de vastgelegde string te verkleinen als het er niet in slaagt een overeenkomst tussen de tekst en het patroon te vinden. Dit mechanisme werkt echter niet altijd zoals we zouden willen. Beschouw het volgende voorbeeld. We willen de tekst 'That is' vervangen door de tekst 'That's'. Vanwege de hebzucht van de kwantor wordt de reguliere expressie '.*is' echter gekoppeld aan het tekstfragment vanaf het begin van de regel. tot de laatste "is" gevonden:


$text =~ s/.*is/Dat"s/;
print $teksten;
Is dat het niet?

Om kwantoren minder hebzuchtig te maken, namelijk om ze de minimale string te laten vastleggen waarmee de reguliere expressie vergelijkbaar is, moet je na de kwantor zetten vraagteken. De kwantoren hebben dus de volgende vorm:

  • *? - nul of meer overeenkomsten,
  • +? - een of meer wedstrijden,
  • ?? - nul wedstrijden of één wedstrijd,
  • (N)? - precies n overeenkomsten,
  • (N,)? - minstens n overeenkomsten,
  • (n,m)? - minimaal n matches, maar niet meer dan m.

Houd er rekening mee dat dit de betekenis van de kwantor niet verandert; alleen het gedrag van het zoekalgoritme verandert. Als tijdens het matchen van het sjabloon en de tekst het prototype op unieke wijze wordt bepaald, zal het backtracking-algoritme de ‘hebzucht’ van zo’n kwantificator vergroten op dezelfde manier als het de eetlust van zijn collega-kwantificator beperkt. Als de keuze echter dubbelzinnig is, zal het zoekresultaat anders zijn:

$text = "Dat is wat tekst, nietwaar?";
$text =~ s/.*?is/Dat"s/;
print $teksten;
Dat is een stukje tekst, nietwaar?

Hoe voorloop- en volgspaties te verwijderen

Om leidende witruimtetekens uit een tekenreeks te verwijderen, kunt u de volgende opdracht gebruiken:

$text = "Nu is het tijd.";
$tekst =~ s/^\s+//;
print $teksten;
Dit is het moment.

Om volgspaties af te snijden, is het volgende commando geschikt:

$text = "Nu is het tijd.";
$tekst =~ s/\s+$//;
print $teksten;
Dit is het moment.

Om zowel voorloop- als volgspaties bij te snijden, is het beter om deze twee opdrachten opeenvolgend aan te roepen dan een sjabloon te gebruiken dat onnodige spaties in één keer weghaalt. Omdat de procedure voor het matchen van een sjabloon en tekst behoorlijk complex is, is dit het geval eenvoudige bediening Het kan veel langer duren dan je zou willen.

In de tekst moet u bijvoorbeeld de tekst vinden die zich tussen de openings- en sluitingstags bevindt:

$tekst = " bla-bla";
als($tekst=~m!<()>(.*?)/\1!ig) (
druk "\n" af;
}

vindt alle woorden tussen de tags en .

Reguliere expressies hebben hun eigen semantiek: snelheid, haast en terugkeer. Als de *-kwantificator in veel gevallen overeenkomt, wordt het langste resultaat afgedrukt. Dit is hebzucht. Snel: Zoeken probeert zo snel mogelijk te vinden. "Text"=~/m*/ , wat betekent dat er geen m tekens zijn, maar als resultaat wordt de waarde 0 geretourneerd. Die. formeel 0 of meer tekens.

$test="aooooee ooaao";
$test=~s/o*/e/;
print $test;
eaaoooo oooo

omdat 1 stapelelement 0 of meer tekens bevat.

Als we de kwantificator g toevoegen, zal het resultaat er als volgt uitzien:

Eeaeeeeeeeeeeeeeeee

omdat de regel 13 plaatsen bevat waar o kan verschijnen, inclusief lege plaatsen.

Modificatoren:

  • /i negeer hoofdlettergebruik
  • /x negeer spaties in het patroon en laat commentaar toe.
  • /g-modifier om waar mogelijk zoeken/vervangen toe te staan
  • /gc-positie wordt niet opnieuw ingesteld als de zoekopdracht mislukt.
  • /s-overeenkomsten zijn toegestaan. met \n wordt $* genegeerd.
  • /m zorgt ervoor dat ^ en $ overeenkomen voor het begin en einde van de regel in interne regeleinden
  • /o één keer compileren
  • /e de rechterkant van s/// vertegenwoordigt de code die wordt uitgevoerd
  • /ee de rechterkant van s/// wordt uitgevoerd, waarna de geretourneerde waarde opnieuw wordt geïnterpreteerd.

bij het aanroepen van gebruikslandinstelling wordt rekening gehouden met lokale instellingen. De /g-modifier kan een array met waarden vullen @nums = m/(\d+)/g; maar dit werkt voor niet-overlappende overeenkomsten. Om overeenkomsten te vinden, moet je de operator?=... gebruiken. Als breedte = 0, blijft het zoekmechanisme op dezelfde plaats. De gevonden gegevens blijven tussen de haakjes staan. Als er een /g-modificator is, blijft de huidige positie hetzelfde, maar gaat één teken vooruit.

$nummers="123456789";
@one=$getallen=~/(\d\d\d)/g;
@twee=$getallen=~/(?=(\d\d\d))/g;
druk "@één \n" af;
druk "@twee\n" af;

De m- en s-modificatoren zijn nodig om te zoeken naar reeksen tekens die een nieuwe regel bevatten. Met s komt de punt overeen met \n en negeert $* . m zorgt ervoor dat ^ en $ voor en na \n overeenkomen. e de rechterkant is tevreden als programmacode: perl -i -n -p -e "s/(.)/lc()/g" *.html converteert alle tekens in alle *.html-bestanden van de huidige map naar kleine letters.

6.4.1. Syntaxis van reguliere expressies

Reguliere expressies zijn patronen voor het zoeken naar gespecificeerde combinaties van tekens in tekstreeksen en het vervangen ervan door andere combinaties van tekens (deze bewerkingen worden dienovereenkomstig genoemd patroonafstemming En vervanging). Een reguliere expressie in PERL ziet er zo uit

/patroon/modificatoren

Patroon is hier een tekenreeks die een reguliere expressie definieert, en modificatoren zijn optionele éénletterige tekens die de regels specificeren voor het gebruik van deze reguliere expressie.

Een reguliere expressie kan uit reguliere tekens bestaan; in dit geval komt het overeen met de gegeven combinatie van tekens in de string. De expressie /cat/ komt bijvoorbeeld overeen met de gemarkeerde subtekenreeksen in de volgende regels: " kat oké", "voor kat", "j kat De echte kracht van reguliere PERL-expressies komt echter voort uit de mogelijkheid om special te gebruiken metatekens.

Tabel 6.9. Metatekens in reguliere expressies
Symbool Beschrijving
\ Voor karakters die doorgaans letterlijk worden geïnterpreteerd, betekent dit dat het volgende karakter een metakarakter is. /n/ komt bijvoorbeeld overeen met de letter n, en /\n/ komt overeen met het teken voor de nieuwe regel.
Voor metatekens betekent dit dat het personage letterlijk moet worden genomen. /^/ vertegenwoordigt bijvoorbeeld het begin van een regel, terwijl /\^/ eenvoudigweg overeenkomt met het teken ^. /\\/ komt overeen met de backslash \.
^ Komt overeen met het begin van een regel (zie modifier).
$ Komt overeen met het einde van een regel (zie modifier).
. Komt overeen met elk teken behalve een regeleinde (zie modifier).
* Komt overeen met het herhalen van het vorige karakter nul of meer keren.
+ Komt overeen met het herhalen van het vorige personage een of meerdere keren.
? Komt overeen met het herhalen van het vorige teken nul of één keer.
(patroon) Komt overeen met string patroon En .
X| j Meewerkend X of j.
{ N} N niet-negatief getal. Komt precies overeen N voorkomens van het vorige teken.
{ N,} N niet-negatief getal. Meewerkend N of meer exemplaren van het vorige teken. /x(1,)/ is gelijk aan /x+/. /x(0,)/ is gelijk aan /x*/.
{ N, M} N En M niet-negatieve cijfers. Voldoet aan maar liefst N en niets meer dan M voorkomens van het vorige teken. /x(0,1)/ is gelijk aan /x?/.
[ xyz] Komt overeen met elk teken dat tussen vierkante haakjes staat.
[^ xyz] Komt overeen met elk teken behalve de tekens tussen vierkante haakjes.
[ A- z] Komt overeen met elk teken in het opgegeven bereik.
[^ A- z] Komt overeen met elk teken behalve die in het opgegeven bereik.
\A Komt overeen met het belsymbool (BEL).
\A Komt alleen overeen met het begin van een regel, zelfs met de modifier.
\B Komt overeen met een woordgrens, d.w.z. de positie ertussen \w En \W in welke volgorde dan ook.
\B Komt overeen met elke andere positie dan een woordgrens.
\MetX Komt overeen met het teken Ctrl+ X. /\cI/ is bijvoorbeeld equivalent aan /\t/.
\C Komt overeen met één byte, zelfs met de gebruiksrichtlijn utf8.
\D Komt overeen met de figuur. Equivalent.
\D Komt overeen met een niet-numeriek teken. Gelijk aan [^0-9].
\ e Komt overeen met het escape-teken (ESC).
\E Het einde van transformatie \L, \Q, \U.
\F Komt overeen met het teken Format Translation (FF).
\G Komt overeen met de positie in de string die gelijk is aan pos() .
\l Converteert het volgende teken naar kleine letters.
\L Converteert tekens naar kleine letters tot \E.
\N Komt overeen met regeleinden.
\Peigendom Komt overeen met Unicode-tekens die de eigenschap hebben eigendom. Als eigendom \P(eigendom} .
\Peigendom Komt overeen met Unicode-tekens die de eigenschap niet hebben eigendom. Als eigendom gespecificeerd door meerdere tekens, gebruik dan de syntaxis \P(eigendom} .
\Q Voegt een teken "\" toe vóór metatekens tot \E.
\R Komt overeen met het Carriage Return-teken (CR).
\S Komt overeen met het spatiekarakter. Equivalent aan /[ \f\n\r\t]/.
\S Komt overeen met elk teken dat geen witruimte bevat. Equivalent aan /[^ \f\n\r\t]/.
\T Komt overeen met het tabteken (HT).
\ u Converteert het volgende teken naar hoofdletters.
\U Converteert tekens naar hoofdletters tot \E.
\w Komt overeen met een Latijnse letter, cijfer of onderstrepingsteken. Gelijk aan / /.
\W Komt overeen met elk ander teken dan een letter, cijfer of onderstrepingsteken. Equivalent aan /[^A-Za-z0-9_] /.
\X Komt overeen met de volgorde Unicode-tekens uit het hoofdsymbool en een reeks diakritische tekens.<(?:\PM\pM*)>/.
Gelijk aan /C \z
\Z Komt alleen overeen met het einde van de regel, zelfs met de modifier.
\ N N Komt alleen overeen met het einde van een regel of een regeleinde aan het einde van een regel, zelfs met de modifier. N positief getal. Meewerkend. Als er minder linkerhaakjes vóór dit teken staan ​​dan N, En N.
\0 N N — > 9, dan gelijk aan \0 octaal getal N, niet groter dan 377. Komt overeen met een teken met een octale code
. /\011/ is bijvoorbeeld gelijk aan /\t/.N N\X N hexadecimaal getal bestaande uit twee cijfers. Komt overeen met een teken met een hexadecimale code
. /\x31/ is bijvoorbeeld gelijk aan /1/.N} N\X( N hexadecimaal getal bestaande uit vier cijfers. Komt overeen met Unicode-tekens met hexadecimale code

. /\x(2663)/ is bijvoorbeeld gelijk aan /♣/.

6.4.2. Modificatoren

Verschillende reguliere expressiebewerkingen gebruiken verschillende modifiers om de uitgevoerde bewerking te specificeren. ^ En $ Vier modificatoren hebben echter een algemeen doel. . komt overeen met elk teken, inclusief regeleinden. \ Staat spaties en opmerkingen toe. Spaties zonder voorafgaand teken # en niet ingesloten, worden genegeerd. Symbool

begint een opmerking, die ook wordt genegeerd.

6.4.3. Unicode- en POSIX-tekenklassen

We kunnen de syntaxis in reguliere expressies gebruiken

[:klas:]

waarbij klasse de naam van de POSIX-tekenklasse specificeert, d.w.z. de mobiele standaard voor de C-taal. Wanneer u de use utf8-richtlijn gebruikt, in plaats van POSIX-klassen, kunt u Unicode-tekenklassen in de constructie gebruiken

\p(klasse)

De volgende tabel geeft een overzicht van alle POSIX-tekenklassen, de overeenkomstige Unicode-tekenklassen en eventuele metatekens.
Tabel 6.10. Karakter klassen POSIX Unicode Beschrijving
Metakarakter alfa IsAlfa
Brieven alnum IsAlnum
Letters en cijfers ascii IsAscii
ASCII-tekens ctrl IsCntrl
Controlekarakters cijfer \D IsDigit
Nummers grafiek IsGraf
Letters, cijfers en leestekens lager Islager
Kleine letters afdrukken IsAfdrukken
Letters, cijfers, leestekens en spatie punt IsPunt
Leestekens ruimte \S IsRuimte
Ruimte tekens bovenste IsBoven
Hoofdletters woord \w IsWoord
Letters, cijfers en onderstrepingstekens xcijfer IsXCijfer

Hexadecimale cijfers Bijvoorbeeld, decimaal getal

kan op een van de volgende drie manieren worden ingesteld:

/\d+/ /[:digit:]+/ /\p(IsDigit)+/ # gebruik utf8

Om aan te geven dat een symbool niet tot een bepaalde klasse behoort, worden de constructies gebruikt

[:^klasse:] \P(klasse)

De volgende uitdrukkingen hebben bijvoorbeeld dezelfde betekenis:

[:^cijfer:] \D \P(IsCijfer) [:^spatie:] \S \P(IsSpatie) [:^woord:] \W \P(IsWoord)

6.4.4. Substrings onthouden Het gebruik van haakjes in een reguliere expressie zorgt ervoor dat de subtekenreeks die overeenkomt met het patroon tussen de haakjes, wordt opgeslagen speciale buffer N. Om toegang te krijgen N De e opgeslagen subtekenreeks binnen de reguliere expressie gebruikt de constructie \ N, Waar N, en daarbuiten $

If (/(.)\1/) ( # zoek naar het eerste herhalende teken, print ""$1" is het eerste herhalende teken\n"; ) if (/Tijd: (..):(..):(. .)/ ) ( # extraheer tijdcomponenten $uren = $1; $minuten = $2; $seconden = $3; )

Naast de $1 , $2 , variabelen zijn er nog een aantal speciale variabelen die de resultaten van de laatste bewerking opslaan met een reguliere expressie, namelijk:

Hier is een voorbeeld:

"AAA111BBB222"=~/(\d+)/; druk "$`\n" af; # AAA-afdruk "$&\n"; # 111 druk "$"\n" af; # BBB222 druk "$+\n" af; # 111

Al deze speciale variabelen behouden hun waarden tot het einde van het omsluitende blok of tot de volgende succesvolle patroonmatch.

6.4.5. Geavanceerde voorbeelden

PERL bevat verschillende aanvullende constructies die in reguliere expressies kunnen worden gebruikt om de mogelijkheden ervan te vergroten. Al deze constructies staan ​​tussen haakjes en beginnen met een symbool? , wat hen onderscheidt van het onthouden van substrings.

(?#tekst) Opmerking. De hele structuur wordt genegeerd. (?modificatoren-modificatoren) Schakelt het opgegeven in of uit. Modifiers vóór het - symbool zijn ingeschakeld, en die na het symbool zijn uitgeschakeld. Voorbeeld:

If (/aaa/) ( ) # hoofdlettergevoelige overeenkomsten if (/(?i)aaa/) ( ) # hoofdlettergevoelige overeenkomsten

(?:patroon) (?modificatoren-modificatoren:patroon) Hiermee kunt u subexpressies van een reguliere expressie groeperen zonder de gevonden overeenkomst te onthouden. (?=patroon) Het tweede formulier schakelt bovendien het opgegeven . De expressie /ko(?:t|shka)/ is bijvoorbeeld een korte versie van de expressie /cat|cat/. (?!patroon) Matchen met vooruitkijken zonder de gevonden match te onthouden. /Windows (?=95|98|NT|2000)/ komt bijvoorbeeld overeen met "Windows" in de tekenreeks "Windows 98", maar komt niet overeen met de tekenreeks "Windows 3.1". Na het matchen gaat het zoeken verder vanaf de positie naast de gevonden match, zonder vooruit te kijken. (?<=patroon) Inconsistentie met vooruitkijken zonder de gevonden match te onthouden. /Windows (?!95|98|NT|2000)/ komt bijvoorbeeld overeen met "Windows" in de tekenreeks "Windows 3.1", maar komt niet overeen met de tekenreeks "Windows 98". Na het matchen gaat het zoeken verder vanaf de positie naast de gevonden match, zonder vooruit te kijken.<=\t)\w+/ соответствует слову, следующему за символом табуляции, и символ табуляции не включается в $& . Фрагмент, соответствующий заглядыванию назад, должен иметь фиксированную ширину. (?patroon
) Matchen met terugkijken zonder de gevonden match te onthouden. De uitdrukking /(?Inconsistentie met terugkijken zonder de gevonden match te onthouden. De uitdrukking /(?

Tot nu toe hebben we reguliere expressies tussen //-tekens geplaatst. In feite worden de scheidingstekens van een reguliere expressie bepaald door de q-bewerking die we erop toepassen. In deze sectie worden alle PERL-bewerkingen met reguliere expressies in detail beschreven.

6.4.6.1. Patroonaanpassing

Syntaxis: /patroon/modificatoren M/ patroon/modificatoren

patroon en retourneert waar of onwaar, afhankelijk van het resultaat van de wedstrijd.

De te matchen string wordt gegeven door de linker operand van de =~ of !~ bewerking, bijvoorbeeld: $mijnnummer = "12345"; if ($mijnnummer =~ /^\d+$/) ( # als de string $mijnnummer bestaat uit decimale cijfers

, Dat… ... )

Als de string niet is opgegeven, wordt de inhoud van de speciale variabele $_ vergeleken. In het bijzonder kan het vorige voorbeeld als volgt worden herschreven:

$_ = "12345"; als (/^\d+$/) ( ... )

Als de reguliere expressie is ingesloten in // , dan is de voorloop m optioneel. Met de leidende m-constructie kunt u alle tekens gebruiken die zijn toegestaan ​​in q-bewerkingen als scheidingstekens voor reguliere expressies. Nuttige speciale gevallen: patroon

Als Als er geen modifier is opgegeven G

en het resultaat van de match wordt aan de lijst toegewezen. Als de match mislukt, wordt er een lege lijst geretourneerd. Het resultaat van een succesvolle match hangt af van de aanwezigheid van haakjes in het patroon. Als er geen zijn, wordt lijst (1) geretourneerd.

Anders wordt een lijst geretourneerd die bestaat uit de waarden van de variabelen $1, $2, enz., d.w.z. een lijst met alle onthouden substrings.

Volgend voorbeeld Als er geen modifier is opgegeven($w1, $w2, $rest) = ($x =~ /^(\S+)\s+(\S+)\s*(.*)/);

plaatst het eerste woord van de string $x in de variabele $w1, het tweede woord van de string in de variabele $w2, en de rest van deze string in de variabele $rest.

Wijziger

maakt de globale patroonvergelijkingsmodus mogelijk, d.w.z. zoeken naar alle overeenkomsten in een string. Het gedrag ervan is afhankelijk van de context. Als het matchresultaat aan een lijst wordt toegewezen, wordt een lijst met alle onthouden substrings geretourneerd. Als het patroon geen haakjes bevat, wordt een lijst met alle overeenkomsten met het patroon geretourneerd alsof het volledig tussen haakjes staat. Volgend voorbeeld Als er geen modifier is opgegeven$_ = "12:23:45"; @resultaat = /\d+/g; foreach $elem (@result) (print "$elem\n"; ) worden de regels 12, 23 en 45 weergegeven.. Als u een tekenreeks wijzigt, wordt ook de zoekpositie in die tekenreeks opnieuw ingesteld.

Extra functies levert het metateken \G, dat alleen betekenis heeft in combinatie met een modifier Als er geen modifier is opgegeven. Dit metateken komt overeen met de huidige zoekpositie in de string. Het gebruik van de m/\G/gc-constructie is vooral handig voor het schrijven van lexicale analysatoren die goed presteren diverse acties

voor lexemen die in de geanalyseerde tekst voorkomen. Volgend voorbeeld

$_ = "Woord1, woord2 en 12345."; LOOP: ( print("nummer "), voer LOOP opnieuw uit als /\G\d+\b[,.;]?\s*/gc; print("woord "), voer LOOP opnieuw uit als /\G+\b[,. ;]?\s*/gc; print("onbekend "), voer LOOP opnieuw uit als /\G[^A-Za-z0-9]+/gc ) zal weergeven woordreeks

woord woord nummer.

Syntaxis: ?patroon 6.4.6.2. Afstemming op één patroon patroon?

? patroon M?

Dit ontwerp is volledig vergelijkbaar met m/<>/ met het enige verschil: succesvolle patroonmatching vindt slechts één keer plaats tussen aanroepen van reset() . Dit is bijvoorbeeld handig als we alleen de eerste keer dat een patroon voorkomt in elk bestand uit de set waar we naar kijken, moeten vinden, bijvoorbeeld: }

Terwijl(

Syntaxis) ( if (?^$?) ( ... # verwerkt de eerste lege regel van het bestand ) ) continue ( reset if eof; # reset status ?? for volgende bestand/modificatoren

6.4.6.3. Een reguliere expressie maken volgende bestand:qr/ modificatoren snaar volgende bestand Deze constructie creëert een reguliere expressie met de tekst

en modificatoren

en compileert deze. Als scheidingstekens ""-tekens zijn, dan is er sprake van tekenreeksinterpolatie

O

Syntaxis Eenmaal gemaakt, kan een reguliere expressie zelfstandig worden gebruikt of als een fragment van andere reguliere expressies. Voorbeelden: patroon/volgende bestand/modificatoren

$re = qr/\d+/; $string =~ /\s*$(re)\s*/; # opname in een andere reguliere expressie $string =~ $re; # aangepast gebruik $string =~ /$re/; # hetzelfde $re = qr/$header/is; s/$re/tekst/; # hetzelfde als s/$header/text/is patroon 6.4.6.4. Vervanging volgende bestand:S/ Deze bewerking vergelijkt een gegeven string met een patroon en vervangt de gevonden fragmenten door de string

. Het retourneert het aantal gemaakte vervangingen, of false (meer precies, een lege string) als de match mislukte. De te matchen string wordt gespecificeerd door de linker operand van de =~ of !~ bewerking. Het moet een scalaire variabele, een array-element of een element zijn

associatieve array

, Bijvoorbeeld:

patroon volgende bestand$pad = "/usr/bin/perl"; $pad =~ s|/usr/bin|/usr/local/bin|; $_ = "/usr/bin/perl"; s|/usr/bin|/usr/local/bin|;

Als scheidingstekens ""-tekens zijn, dan is er sprake van tekenreeksinterpolatie patroon wordt niet geproduceerd. Deze constructie creëert een reguliere expressie met de tekst In andere gevallen wordt de steekproef geïnterpoleerd en als deze variabelen bevat, wordt deze voor elke vergelijking samengesteld. Gebruik de modifier om dit te voorkomen

Als de reguliere expressie is ingesloten in // , dan is de voorloop m optioneel. Met de leidende m-constructie kunt u alle tekens gebruiken die zijn toegestaan ​​in q-bewerkingen als scheidingstekens voor reguliere expressies. Nuttige speciale gevallen: patroon(uiteraard als u zeker weet dat de waarden van de variabelen in de steekproef ongewijzigd blijven). is lege regel

, dan wordt in plaats daarvan de laatste succesvol overeenkomende reguliere expressie gebruikt. Als er geen modifier is opgegeven.

Volgend voorbeeld Standaard wordt alleen het eerste gevonden monster vervangen. Om alle exemplaren van een patroon in een string te vervangen, moet je de modifier gebruiken e volgende bestand geeft dat aan volgende bestand is een uitdrukking. In dit geval naar

De functie eval() wordt eerst gebruikt en vervolgens wordt de vervanging uitgevoerd. Voorbeeld:

$_ = "123"; s/\d+/$&*2/e; # $_ = "246" s/\d/$&*2/eg; # hetzelfde Laten we er nog een paar geven typische voorbeelden

met behulp van de vervangingsoperatie. Opmerkingen zoals /**/ verwijderen uit de tekst van een Java- of C-programma:

$program =~ s ( /\* # Begin van commentaar.*? # Minimum aantal tekens \*/ # Einde van commentaar )gsx; Het verwijderen van initiële en achterliggende spaties

in de $var-regel:

Voor ($var) ( s/^\s+//; s/\s+$//; )

De eerste twee velden in $_ herschikken. Merk op dat de vervangende string de variabelen $1 en $2 gebruikt in plaats van de metatekens \1 en \2:

S/([^ ]*) *([^ ]*)/$2 $1/;

Tabbladen vervangen door spaties uitgelijnd met kolommen die deelbaar zijn door acht:

1 while s/\t+/" " x (lengte($&)*8 - lengte($`)%8)/e;

Syntaxis 6.4.6.5. Transliteratie :tr//lijst1/modificatoren lijst2 :tr//lijst1/modificatoren

j/ :tr/ Transliteratie bestaat uit het vervangen van alle tekens uit de lijst lijst1 overeenkomende tekens uit de lijst

. Het retourneert het aantal vervangen of verwijderde tekens. Lijsten moeten bestaan ​​uit individuele tekens en/of bereiken van de vorm a-z . De te converteren string wordt gespecificeerd door de linkeroperand van de =~ of!~ bewerking. Het moet een scalaire variabele, een array-element of een associatief array-element zijn, bijvoorbeeld:$test = "ABCDEabcde"; $test =~ tr/A-Z/a-z/; # vervanging

kleine letters

naar hoofdletters

Als de string niet is opgegeven, wordt de vervangingsbewerking uitgevoerd op de speciale variabele $_. In het bijzonder kan het vorige voorbeeld als volgt worden herschreven: :tr/$_ = "ABCDEabcde"; tr/A-Z/a-z/; lijst1 We kunnen elk symbool gebruiken dat is toegestaan ​​in q-operaties in plaats van //. Als dan tussen dubbele haakjes

Deze bewerking wordt gewoonlijk tr genoemd. Het synoniem y is geïntroduceerd voor fanatici van de sed-editor en wordt alleen door hen gebruikt.

Volgend voorbeeld worden de regels 12, 23 en 45 weergegeven. Transliteratie ondersteunt de volgende modifiers: :tr/ zorgt ervoor dat alle tekens die niet in de lijst voorkomen, worden getranslitereerd

. De bewerking tr/a-zA-Z/ /c vervangt bijvoorbeeld alle niet-Latijnse tekens door spaties. lijst1 Standaard als :tr/ korter dan :tr/, wordt het aangevuld met het laatste symbool, en als het leeg is, wordt het gelijkgesteld aan (dit is handig voor het tellen van het aantal tekens van een bepaalde klasse op een regel). Wijziger :tr/ D lijst1 verandert deze regels: alle karakters uit

Volgend voorbeeld , waar geen correspondentie in bestaat, worden van de lijn verwijderd. De bewerking tr/a-zA-Z//cd verwijdert bijvoorbeeld alle niet-lettertekens uit een string.

S verwijdert herhalingen: als meerdere karakters op rij worden vervangen door hetzelfde karakter, blijft er slechts één exemplaar van dit karakter over. Met de bewerking tr/ / /s worden bijvoorbeeld herhaalde spaties uit een tekenreeks verwijderd. En Modificatoren C

U

zijn ontworpen om tekens van de systeemcodering naar UTF-8 te converteren en omgekeerd.

De eerste geeft de broncodering aan, en de tweede geeft de resultaatcodering aan. Zo zal tr/\0-\xFF//CU bijvoorbeeld een string van de systeemcodering naar UTF-8 converteren, en zal tr/\0-\xFF//UC de omgekeerde conversie uitvoeren. Transliteratie wordt gedaan zonder lijsten met tekens te interpoleren, dus om variabelen erin te gebruiken moet u bijvoorbeeld de functie eval() aanroepen.> Reguliere expressies in Perl Reguliere expressies worden gebruikt om patronen in strings te vinden. Bijvoorbeeld om een ​​specifieke naam in het telefoonboek te vinden, of bijvoorbeeld alle namen die beginnen met de letter "a". Werken met reguliere expressies is een van de krachtigste en nuttigste, en tegelijkertijd het moeilijkst te begrijpen. Perl-functies

. We hopen dat je na het lezen van dit artikel begrijpt hoe krachtig en

handig hulpmiddel
. Nadat u enige ervaring heeft opgedaan, kunt u deze kansen in uw voordeel gebruiken.
Exploitanten

Perl gebruikt drie operatoren om met reguliere expressies te werken:
- vergelijkingsoperator (matching - m//), vervangingsoperator
(vervanging s///) en vertaaloperator (vertaling - tr///).

Alle drie de operators gebruiken standaard de variabele $_, dus verder zullen we dat doen totdat de bewerkingen =~ en!~ worden gepresenteerd
gebruik het.
Vergelijkingsoperator
scheidingsteken (meestal is dit een schuine streep - /, maar in principe kan dit wel
kan bijna elk teken zijn), een patroon en een ander scheidingsteken (hetzelfde
zoals de eerste :).

Vergelijkingsoperator
$_ = ;
als (m/hallo/) (
print "hallo gebruiker\n";
}

if ($input("siteurl") =~ #http://#) (
print $input("siteurl");
}

In dit voorbeeld wordt gecontroleerd of de string terugkomt van
standaard invoer, het woord "hallo". Als dat het geval is, komt de m//-operator terug
waarde 1), dan wordt de zinsnede "hallo gebruiker" teruggestuurd naar de standaarduitvoer.

Opmerking: eigenlijk is het teken "m" optioneel
De verklaring in dit voorbeeld zou er eenvoudigweg als /hello/ uit kunnen zien.

Vervangingsoperator vindt alle substrings in een string die voldoen
patroon, en vervangt ze door een andere waarde. Neem dit op
operator bestaat uit de letter s, wat aangeeft dat dit inderdaad het geval is
vervangingsoperator van zowel het origineel (wat te vervangen) als de vervangingsoperator (voor
wat te vervangen) sjablonen gescheiden door scheidingstekens.

Vervangingsoperator
$_ = "Mijn naam is Fred";
# oh nee, mijn naam is Jonathan!
s/Fred/Jonathan/;

In dit voorbeeld worden in de regel $_ alle woorden Fred gewijzigd in Jonathan.

Vertaaloperator voert ook vervanging uit, maar op een iets andere manier
karakter - het wordt gebruikt om te vervangen individueel symbool sommige
andere (specifieke) symbolen. De syntaxis van deze operator is vergelijkbaar met
de syntaxis van de substitutie-operator, met het verschil dat dit eerst het geval is
begint uiteraard met de letters tr, en tussen de scheidingstekens staat nee
sjablonen en groepen symbolen, de eerste - de originele symbolen, de tweede -
jokertekens en de bijbehorende tekens moeten verschijnen
identieke posities in hun groepen - als je wilt vervangen,
bijvoorbeeld Latijnse "m" tot Cyrillische "m", ze moeten op staan
identieke plaatsen: "m" - in de eerste groep tekens, "m" - in de tweede.

Vertaaloperator
$_ = "Hoi.daar, mijn.naam.is.jonathan,";
tr/.,/ !/;

In dit voorbeeld worden alle komma's gewijzigd in uitroeptekens, A
punten naar spaties.

Modificatoren

De mogelijkheden van elk van deze operators kunnen worden uitgebreid met
modificatoren. Modifiers zijn grofweg symbolen die
worden toegevoegd aan de operator (bijvoorbeeld zoals deze - s/fred/Jonathan/i), over praten
hoe hij de werkwaarde moet ontleden.

Modificaties voor de vergelijkingsoperator:

  • x - hiermee kunt u uitgebreide reguliere expressies gebruiken;

Modificatoren voor de vervangingsoperator:

  • e - evalueert de substitutie-expressie vóór substitutie;
  • g - vindt alle gevonden substrings;
  • i - negeert hoofdlettergebruik van tekens in de string;
  • m - behandelt de string als een waarde met meerdere regels;
  • s - behandelt de tekenreeks als een waarde van één regel;
  • x - hiermee kunt u uitgebreide reguliere expressies gebruiken.

Modificatoren

$_ = "Mijn naam is Fred";
s/fred/Jonathan/i; # Mijn naam is Jonathan
s/jonathan/routine()/ie; # Mijn naam is

Bewerkingen =~ en!~

De operatoren =~ en!~ maken gebruik mogelijk met de m//, s/// en
tr /// alle variabelen, niet alleen $_, die door deze wordt gebruikt
standaardoperatoren.

De operator =~ voert dezelfde functies uit als de toewijzingsoperator "="
(indien gebruikt met de operatoren s/// en tr///) en de operator
"eq"-vergelijkingen (indien gebruikt met de operator m//).

Bediening =~
$name = "mijn naam is Fred";
$naam =~ s/fred/Jonathan/ig;

$string = "hallo wereld";
if ($string =~ /hallo/i) (
print "helloworlded in deze string.";
}

Op dezelfde manier wordt de operator!~ op dezelfde manier gebruikt als de operator "ne" (its
de spelling is vergelijkbaar met de numerieke vergelijkingsbewerking!=), die wordt gebruikt
alleen met vergelijkingsoperator en betekent ontkenning van tevredenheid
sjabloon.

Operatie!~
$string = "goed";
if ($string !~ /bad/) (
print "Hé, het valt nog mee!";
}

Geheugen

En tot slot - over de mogelijkheid om gemakkelijker met de resultaten te werken
het verwerken van reguliere expressies, namelijk het afzonderlijk opslaan ervan
variabelen. Dergelijke variabelen zijn de vooraf gedefinieerde $&, $`, $", en
reeks variabelen $1, $2, ..., $9.

$& variabel

Deze variabele is bedoeld om een ​​stringfragment op te slaan dat
voldeed aan het patroon gespecificeerd door de reguliere expressie. Het is handig binnen
in dergelijke gevallen, bijvoorbeeld als u een getal in een string moet vinden, maar
Welk nummer dit is, is niet bekend. Hier ziet u hoe het eruit zou kunnen zien:

$string = "fout 404."
$string =~ m/\d+/;

Variabelen $` en $"

Deze variabelen worden gebruikt om fragmenten op te slaan die dat niet zijn
voldeed aan het patroon, namelijk de substrings die ervoor en erna komen
resultaat dienovereenkomstig. Met andere woorden, na een operatie, b.v.
Ter vergelijking: de waarde van de originele string is verdeeld in drie delen: deel,
die bij de sjabloon past, en de fragmenten die ervoor gaan en
na haar. Deze onderdelen worden in de variabelen $&, $` en $" geplaatst
respectievelijk. (Merk op dat in de eerste variabele -
backquote, en in de tweede - vooruit). Laten we naar de vorige kijken
voorbeeld.

$string = "fout 404."
$string =~ m/\d+/;

$nummer = $&; # $nummer bevat "404"
$voor = $`; # $before bevat "fout"
$na = $"; # $na bevat "."

Variabelen $1..$9

Deze variabelen worden gebruikt om stringfragmenten op te slaan
voldeed aan de overeenkomstige specifieke fragmenten van de sjabloon. IN
in de sjabloon worden fragmenten gemarkeerd met behulp van haakjes. Elk fragment
het nummer wordt gemarkeerd in de volgorde waarin ze zich bevinden, en
de corresponderende variabele zal zijn waarde bevatten.

$string = "dit moet in hoofdletters zijn";
$string =~ s/(bovenste\w+)/uc($1)/;
# $string = "Dit moet in HOOFDLETTERS zijn"

$string = "15 appels, 2 voedsel, 3 repen";
while ($string =~ m/(\d+) (\w+)/g) (
druk "$2: $1\n" af;
}
# Appels afdrukken: 15
# voedsel: 2
# balken: 3

Nikolaj Matkovski,
11.05.2006.