Reguliere expressies elke letter. Syntaxis van reguliere expressies

Geheimen van reguliere expressies

Deel 1. Dialecten en capaciteiten. Reguliere expressies schrijven

Inhoud serie:

1. Inleiding. Gebruiken we reguliere expressies ten volle?

Als je nadenkt over de vraag: “Wat is een ‘reguliere uitdrukking’ in het algemeen?”, dan zal het antwoord niet meteen worden gevonden. We kunnen zeggen dat dit een gespecialiseerde taal is voor het beschrijven van een tekenpatroon (reeks tekens) voor het zoeken in tekstreeksen. Het belangrijkste hier is dat bij het zoeken naar overeenkomsten een karakter-voor-karakter vergelijking wordt uitgevoerd. J.E.F. Friedl, auteur van de encyclopedie over reguliere expressies (Mastering Regular Expressions), adviseert om de gewoonte te ontwikkelen om reguliere expressies letterlijk te interpreteren. Als je bijvoorbeeld naar het patroon "^cat" kijkt, wat betekent "de regel moet beginnen met het woord cat", zou je als volgt redeneren: "er zal een overeenkomst worden gevonden als we aan het begin van de regel staan ​​en de teken c onmiddellijk gevolgd door het teken a, onmiddellijk gevolgd door een symbool t". Hierdoor kunt u de betekenis en essentie van een reguliere expressie het meest nauwkeurig beoordelen.

De meeste gebruikers weten dat ze om te zoeken gewoon een voorbeeldwoord hoeven in te voeren. In een webbrowser ontvangt u bijvoorbeeld in het veld "Zoeken" na het invoeren van "Linux" een lange lijst met links naar pagina's waarvan de tekst overeenkomt met het opgegeven patroon "Linux". Lokaal bestandssysteem gebruik grep "Linux" commando of grafische hulpmiddelen zoekopdracht.

Niet allemaal, maar veel gebruikers weten hoe ze metatekens (* . ?) in zoekpatronen moeten gebruiken. Nog minder mensen zijn op de hoogte van de mogelijkheid om modifiers en andere geavanceerde tools te gebruiken voor het construeren van reguliere expressies, d.w.z. in veel gevallen wordt amper een derde van het vermogen van de reguliere expressie-engine gebruikt. Waarom niet proberen de efficiëntie te vergroten?

2. Verschillende dialecten van reguliere expressies. POSIX-naleving

Over het algemeen zijn er twee hoofddialecten (of typen) reguliere expressies: eenvoudig en uitgebreid. Tegelijkertijd is de grens daartussen voorwaardelijk en wordt deze in de loop van de tijd steeds minder duidelijk.

De programma's vi(m), sed, grep, less, ed, expr, lex begrijpen alleen eenvoudige reguliere expressies, terwijl de hulpprogramma's (g)awk, egrep, evenals tolken van de Perl-, Tcl- en Python-talen, uitgebreide reguliere expressies begrijpen. uitdrukkingen. Tegelijkertijd heeft elk van de programma's zijn eigen verbeteringen, d.w.z. subdialecten van reguliere expressies worden gemaakt. Laten we eens kijken naar de overeenkomsten en verschillen tussen deze dialecten.

2.1. Algemeen reguliere expressieschema

Normaal gesproken bestaat een reguliere expressie uit drie hoofdonderdelen:

  1. Anker – definieert de positie van de sjabloon in een tekstregel:
    • ^ – anker dat het begin van de lijn definieert;
    • $ is een anker dat het einde van de regel definieert.
  2. Een set (reeks) tekens – om overeenkomsten in te zoeken gegeven posities regels tekst:
    • het puntteken (.) komt overeen met elk willekeurig teken;
    • alfanumerieke tekens en spaties vertegenwoordigen zichzelf;
    • andere symbolen - interpretatie hangt af van het dialect.
  3. Modifier – stelt het aantal herhalingen in van het vorige teken of de reeks tekens (afhankelijk van het dialect):
    • * – elk aantal herhalingen van een symbool/set, inclusief nul;
    • ? – komt overeen met nul of één exemplaar van een teken/set;
    • + – komt overeen met één of meer symbool/set-instanties.

Voorbeeld: u moet alle richtlijnen voor de definitie van macroconstanten vinden in broncode in S-taal.

grep "^ *#define.*" *.c *.h

Hierbij wordt er rekening mee gehouden dat aan het begin van de macrodefinitieregel een willekeurig aantal spaties of geen spaties kunnen worden ingevoegd. Het #define-gedeelte van de sjabloon is letterlijk, d.w.z. elk teken wordt geïnterpreteerd "zoals het is". Het laatste deel van de sjabloon betekent 'alle symbolen in welke hoeveelheid dan ook'.

Houd er rekening mee dat het teken ^ alleen wordt geïnterpreteerd als een anker dat het begin van een regel markeert als dit het allereerste teken van het patroon is. Op dezelfde manier markeert het $-teken het einde van een regel, op voorwaarde dat dit het allerlaatste teken van het patroon is. In alle andere gevallen worden deze symbolen letterlijk, d.w.z. vertegenwoordigen zichzelf.

2.2. Tekenbereiken definiëren in reguliere expressies

Als u een teken wilt opgeven uit bepaalde groep alleen bijvoorbeeld digitaal symbool, of gewoon een klinker kleine letters, of alleen leestekens, dan worden vierkante haken gebruikt, waarbinnen de vereiste tekens worden gedefinieerd. Dus:

  • – komt overeen met één digitaal teken uit een bepaalde set;
  • [аееоыеюя] – komt overeen met een van de vermelde klinkers;
  • [,.:;] – komt overeen met een van de leestekens.

Houd er rekening mee dat in het laatste geval de punt tussen vierkante haken zijn speciale status verliest en niet “een teken” aanduidt, maar het teken “punt” zelf.

Doorlopende reeksen tekens kunnen in verkorte vorm worden geschreven met behulp van een koppelteken: het eerste voorbeeld is handiger geschreven als . Bovendien is elke combinatie van bereiken en specifieke tekens toegestaan.

Het is ook mogelijk om gespecificeerde tekensets uit te sluiten van de zoekopdracht, dit gaat als volgt:

  • [^0-9] – komt overeen met elk teken behalve numeriek;
  • [^аеойоуыеюя] – komt overeen met elke letter die GEEN klinker is.

We zullen kennis maken met andere nuances van het definiëren van reeksen tekens tussen vierkante haakjes tijdens het toepassen ervan, en nu zullen we modifiers overwegen aan de hand van het voorbeeld van een zoekpatroon voor een digitaal IP-adres.

2.3. Wijzigingen in het aantal karakterherhalingen

De moeilijkheid hier is dat de *-modifier niet geschikt is voor het zoeken naar een IP-adres - een poging om het patroon *\.*\.*\ te gebruiken. resulteert in regels die elementen van het type 2344.5657.11.00000 bevatten, die geen IP-adressen zijn. Om het aantal herhalingen van tekensets te specificeren, wordt de modifier \(min,max\) gebruikt. Wetende dat elk deel van een IP-adres één tot kan bevatten drie cijfers, schrijven we de modificator in de vorm \(1,3\). Backslash-tekens vóór punten zijn vereist om ze ongedaan te maken speciale status universeel metakarakter. Merk ook op dat de waarde 0 niet wordt gebruikt als de eerste byte van reguliere IP-adressen. Als resultaat krijgen we het volgende zoekpatroon:

grep "\(0,2\)\.\(1,3\)\.\(1,3\)\.\(1,3\)" *.txt

De modifier \(min,max\) werkt alleen in eenvoudige gevallen normale uitdrukkingen. Je kunt \( \) niet gebruiken in uitgebreide reguliere expressies, maar je kunt wel een modifier gebruiken? als het equivalent van de uitdrukking \(0,1\), en de modificator + als het equivalent van de uitdrukking \(1,\). In het tweede geval wordt de komma niet gespecificeerd numerieke waarde- het betekent dat maximaal aantal wedstrijden zijn onbeperkt.

2.4. Een sjabloonelement onthouden en hergebruiken

Dit mechanisme werkt ook alleen in eenvoudige reguliere expressies. (In de programmeertalen Perl, Python, etc. dit mechanisme wordt ondersteund - de grens tussen dialecten wordt steeds minder duidelijk te onderscheiden, weet je nog?)

In eenvoudige reguliere expressies worden de delen van het patroon die zich in de \(\)-constructie bevinden, onthouden en genummerd, waarna ze opnieuw kunnen worden gebruikt. In totaal kunt u maximaal negen genummerde patronen onthouden. Het meest illustratieve voorbeeld van het gebruik van het memorisatiemechanisme is het zoeken naar palindromen (woorden die zowel van links naar rechts als van rechts naar links hetzelfde worden gelezen):

  • \(\)\(\)\2\1 – voor palindromen van vijf letters (bijvoorbeeld niveau, rotor, mevrouw, etc.)
  • \(\)\(\)\(\)\3\2\1 – voor palindromen van zes letters (bijvoorbeeld roder, succus, terret, enz.)

2.5. POSIX-naleving

De POSIX-standaard verdeelt reguliere expressies ook in twee categorieën: BRE (Basic Reguliere Expressies) en ERE (Extended Reguliere Expressies). Metatekens worden in beide categorieën ondersteund. en *, ankers ^ en $, waarbij tekens tussen haakjes worden gegroepeerd (voor BRE worden haakjes geëscaped met een backslash), waarbij kwantoren \(min,max\) worden toegepast op groepen tussen haakjes. Memoriseren en hergebruiken\1...\9 ondersteunt alleen de BRE-categorie, en de kwantoren + en? en het keuzeconstruct – alleen de ERE-categorie.

De POSIX-standaard maakt gebruik van het concept van lokale context (locale) - een reeks parameters die taal- en culturele regels beschrijven: datum- en tijdnotatie, interpretatie van actieve coderingstekens, enz. Dit is niet rechtstreeks van toepassing op reguliere expressies, maar heeft wel invloed op de manier waarop ze functioneren. Bij het werken in een lokale context met UTF-8-codering, overgenomen in bijna alle moderne distributies, worden karakters van het Russische alfabet en hun bereiken correct verwerkt, d.w.z. U kunt bereiken [a-z] en [A-Z] opgeven in zoeksjablonen.

3. Voorbeelden van het samenstellen van nuttige reguliere expressies

Om correct werkende reguliere expressies te creëren, is theorie alleen niet voldoende. Het is noodzakelijk om niet alleen te leren een sjabloon te construeren en te schrijven, maar ook om volledig rekening te houden met de context waarin deze zal worden vergeleken. Het schrijven en verbeteren van een sjabloon is een iteratief proces, waarbij twee hoofdtaken worden opgelost: enerzijds het verkrijgen van alle vereiste regels, zonder de regels te missen die volgens het plan hadden moeten overeenkomen, maar om de een of andere reden niet klopten. overeenkomst; aan de andere kant: sluit alles uit onnodige lijnen, inclusief degenen die volgens het plan moesten worden weggegooid, maar om de een of andere reden samenvielen.

3.1. Een voorbeeld van een sjabloon voor het zoeken naar een geldbedrag geschreven in het formaat "10.000 roebel 00 kopeken."

\(1,\) wrijven\. \(2\) kopeken\.

Noodzakelijke verduidelijking: als een modifier zoals \(min,max\) zowel een komma als mist maximale waarde, dan specificeert deze constructie het exacte aantal verwachte herhalingen van het sjabloonelement. In ons voorbeeld zijn precies twee digitale karakters gedefinieerd die kopeken vertegenwoordigen.

3.2. Een voorbeeld van een sjabloon voor het zoeken naar een URL-reeks die overeenkomt met een webbron op internet:

http://\(1,\)\.[-a-zA-Z0-9_]\(1,\)/*

Noodzakelijke verduidelijking: een koppelteken verliest zijn speciale betekenis als het wordt gespecificeerd op de allereerste positie onmiddellijk na de openingsvierkant haakje in een bereik. Dit patroon kan ook worden gebruikt om “exotische” URL-strings te vinden, zoals http://my.home-server/

In het uitgebreide reguliere expressieformaat zou dit patroon compacter kunnen worden geschreven:

http://+\.[-a-zA-Z0-9_]+/*

Deze notatie wordt bijvoorbeeld begrepen door de hulpprogramma's egrep en awk.

3.3. De sjabloon voor het zoeken naar een HTML-tag ziet er verrassend eenvoudig uit:

<[^>]+>

Komt overeen met elke reeks tekens, behalve één of meer > tussen punthaken. Met andere woorden, er zal ook een tag van één teken worden gevonden

En meer uitgebreide tags zoals


.

3.4. Sjabloonoptie voor het zoeken naar datums

Met geavanceerde reguliere expressies kunt u een enigszins omslachtig, maar toch correct werkend sjabloon schrijven voor het zoeken naar datums die lijken op "13 november 2009":

? (jan|februari|maart|april|mei|jun|juli|aug|sep|okt|nov|dec).* g\.

Het nadeel van dit patroon is dat het niet kan worden gebruikt om datums te vinden oude geschiedenis, bijvoorbeeld '13 november 245'. of 1 januari 88”, maar het is best geschikt voor het werken met moderne documenten (houd rekening met de zoekcontext!).

3.5. Praktische toepassing van genummerde delen van het sjabloon

In de vorige sectie gaf ik al een voorbeeld van een sjabloon voor het zoeken naar palindromen. De functionaliteit ervan kan ook enigszins worden verbeterd door de uitdrukking als volgt te herschrijven:

\(.\)\(.\)\(.\)\3\2\1

Met behulp van deze sjabloon kunt u palindromen van zes tekens vinden, niet alleen in het Engels, maar ook in het Russisch en andere talen, evenals reeksen niet-alfabetische tekens, bijvoorbeeld /*!!*/

Meer op een praktische manier Het gebruik van onthouden en genummerde delen van de sjabloon is om te zoeken naar herhaalde woorden in de buurt, wat het mogelijk maakt om veelvoorkomende fouten (typefouten) in teksten als “for for” te detecteren. Het patroon kan als volgt worden geschreven:

\<\(..*\)\> \<\1\>

Hier worden nog twee reguliere expressie-elementen gebruikt: \< для обозначения начальной границы слова и \>om de uiteindelijke grens van een woord aan te geven. Wij herinneren ons dus alleen maar individuele woorden, niet een reeks karakters. De uitdrukking..* komt overeen met elk woord dat bestaat uit ten minste uit één karakter. Als gevolg hiervan zullen we herhalingstypefouten kunnen vinden zoals “en en”, “niet niet”, “voor voor”, enz.

3.6. Beperking van de grootte van het overeenkomende deel van het patroon

Een ander kenmerk van het ‘karakter’ van reguliere expressies is dat ze ongelooflijk ‘hebzuchtig’ zijn, d.w.z. probeer zoveel mogelijk te matchen lange rij. Door deze ‘hebzucht’ kunnen er onverwachte problemen ontstaan. Er is bijvoorbeeld een patroon voor het zoeken naar een willekeurig aantal tekens tussen aanhalingstekens:

".*"

De zoekreeksen hebben volgende weergave:

"Petrov" "bewaker" "Ivanov" "toeleveringsafdeling" "forwarder" "Sidorov" "administratie" "directeur"

Als het de taak was om alleen het eerste argument (de achternaam van de werknemer) uit de gegeven strings te extraheren, dan zal het hierboven voorgestelde sjabloon dit niet correct uitvoeren, aangezien het tweede aanhalingsteken van het sjabloon overeenkomt met het laatste aanhalingsteken van de string (vanwege de wens om de maximale match te verkrijgen). Het sjabloon wijzigen:

".*" ".*"

lost het probleem alleen op voor de eerste regel, en in de tweede en derde regel is de werkplek ook aan de achternaam gekoppeld - nogmaals, niet wat we nodig hebben!

Dit probleem kan correct worden opgelost met behulp van een reguliere expressie die overeenkomt met de kortste van alle mogelijke stringfragmenten, gelegen tussen twee aanhalingstekens:

"[^"]*"

Hier moet het openingscitaat worden gevolgd door een willekeurig aantal niet-aanhalingstekens totdat het eindcitaat wordt aangetroffen.

4. Conclusie

Zelfs uit de voorbeelden, die verre van de meest complexe waren, die in dit artikel werden beschreven, kon je begrijpen hoe rijk en gevarieerd de mogelijkheden van reguliere expressies zijn. U kunt zelfs rekening houden met het opnameformaat van hun sjablonen in een bijzondere taal programmeren, leren denken en schrijven, waar je jezelf van gaat redden grote hoeveelheid eentonig en vervelend werk.

In het eerste artikel werd het gegeven algemeen idee over reguliere expressies en hun reikwijdte, evenals Korte beoordeling kenmerken van hun dialecten. Er werden voorbeelden overwogen van het samenstellen van reguliere expressies om verschillende problemen op te lossen.

De voortzetting van de serie zal worden gewijd aan praktisch werk met reguliere expressies in specifieke programma's en taalomgevingen.

Bronnen om te downloaden

static.content.url=http://www.site/developerworks/js/artrating/

ArtikelID=487264

ArticleTitle=Geheimen van reguliere expressies: deel 1. Dialecten en mogelijkheden. Reguliere expressies schrijven

Reguliere expressies zijn een veelgebruikte manier om patronen te beschrijven voor het zoeken naar tekst en het controleren of tekst overeenkomt met een patroon. Met speciale metatekens kunt u bijvoorbeeld opgeven dat u zoekt naar een subtekenreeks aan het begin van de invoertekenreeks of bepaald aantal herhalingen van een substring.

Op het eerste gezicht zien reguliere expressies er eng uit (oké, op het tweede gezicht zien ze er nog enger uit ;)).

Ik raad u ten zeerste aan om te “spelen” met het demoprogramma voor Windows REStudio dat in de distributiekit wordt meegeleverd. Hierdoor kunt u het principe van reguliere expressies beter begrijpen en fouten in uw eigen expressies opsporen. TestRExp bevat ook veel voorbeeldexpressies.

Hieronder vindt u een beschrijving van een subset van de syntaxis van reguliere expressies die in bijna alle implementaties werkt en wordt ondersteund door mijn Delphi-bibliotheek, die standaard is opgenomen in Lazarus (Free Pascal).

Laten we beginnen met onze introductie tot reguliere expressies!

Simpele vergelijking

Elk personage komt overeen met zichzelf, tenzij het tot de speciale metatekens behoort die hieronder worden beschreven.

De reeks tekens komt overeen met dezelfde reeks in de invoerreeks, dus het patroon bluh komt overeen met de subtekenreeks bluh in de invoerreeks. Tot nu toe is alles eenvoudig, nietwaar?

Als metatekens of escape-reeksen als reguliere tekens moeten worden behandeld, moeten ze worden voorafgegaan door een \-teken. Het metateken ^ komt bijvoorbeeld meestal overeen met het begin van regels, maar als het wordt geschreven als \^, komt het overeen met het teken ^, \ \ komt overeen met \ enz.

Voorbeelden:

foobar vindt 'foobar' \^FooBarPtr vindt '^FooBarPtr'

Ontsnappingssequenties

Elk teken kan worden gespecificeerd met behulp van een escape-reeks, net zoals dat wordt gedaan in C of Perl: \n betekent het begin van een regel, \t betekent een tab, enz. In het algemeen is \xnn , waarbij nn een reeks hexadecimale tekens is cijfers, betekent teken met ASCII-code nn. Als u een dubbelbyteteken (Unicode) moet opgeven, gebruikt u de notatie \x(nnnn) , waarbij nnnn een of meer hexadecimale cijfers is.

\xnn teken s hexadecimale code nn \x(nnnn) teken met hexadecimale code nnnn (meer dan één byte kan alleen worden opgegeven in de modus (tregexpr_interface.html#unicode))| \t tabblad (HT/TAB), u kunt ook \x09 \n nieuwe lijn(NL), je kunt ook \x0a \r Carriage Return (CR), je kunt ook \x0d| \f formaat vertaling (FF), u kunt ook \x0c| \een oproep (BEL), u kunt ook \x07| \e ontsnappen (ESC), ook \x1b|

Voorbeelden:

foo\x20bar vindt 'foo bar' (let op de spatie in het midden) \tfoobar vindt 'foobar' voorafgegaan door een tab

Lijsten met symbolen

U kunt een lijst definiëren door de tekens tussen . De lijst komt overeen met elk teken dat erin wordt vermeld.

Als het eerste teken van de lijst (onmiddellijk na [) ^ is, dan komt zo'n lijst overeen met elk teken dat niet in de lijst staat.

Voorbeelden:

foobr vindt 'foobar', 'foober', enz. maar niet 'foobbr', 'foobcr', enz. foob[^aeiou]r vindt 'foobbr', 'foobcr', etc.. maar niet 'foobar', 'foober', etc.

Binnen een lijst kan het teken - worden gebruikt om reeksen tekens te definiëren; a-z vertegenwoordigt bijvoorbeeld alle tekens tussen a en z, inclusief.

Als u het teken zelf in de lijst wilt opnemen, plaatst u het aan het begin of einde van de lijst, of laat u het voorafgaan door een \. Als u het teken ] in de lijst wilt opnemen, plaatst u het helemaal aan het begin of laat u het voorafgaan door een \ .

Voorbeelden:

[-az] "a", "z" en "-" "a", "z" en "-" "a", "z" en "-" alle 26 klein Latijnse letters van "a" tot "z" [\n-\x0D] #10, #11, #12, #13. [\d-t] cijfer, "-" of "t". -a] teken uit het bereik "]".."a".

Metakarakters

Metakarakters zijn dat wel Speciale symbolen, het belangrijkste concept in reguliere expressies. Er zijn verschillende groepen metatekens.

Metatekens - lijnscheidingstekens

^ begin van regel $ einde van regel \A begin van tekst \Z einde van tekst. elk teken in de string

Voorbeelden:

^foobar vindt "foobar" alleen als het aan het begin van de regel staat foobar$ vindt "foobar" alleen als het aan het einde van de regel staat ^foobar$ vindt "foobar" alleen als dit het enige woord in de regel foob is .r vindt "foobar", "foobbr", "foob1r" enz.

Het metateken ^ komt standaard alleen overeen met het begin tekst invoeren, en het metasymbool $ staat alleen aan het einde van de tekst. Interne regelscheidingstekens in de tekst komen niet overeen met ^ en $.

Als u tekst echter als meerdere regels moet behandelen, zodat ^ overeenkomt na elk regelscheidingsteken in de tekst, en $ vóór elk scheidingsteken, dan kunt u de modificatie /m opnemen.

De metatekens \A en \Z zijn vergelijkbaar met ^ en $, maar worden niet beïnvloed door de modifier /m, d.w.z. ze komen altijd alleen overeen met het begin en het einde van de gehele invoertekst.

Metakarakter. komt standaard overeen met elk teken, maar als u de modifier /s uitschakelt, dan. komt niet overeen met lijnscheidingstekens.

TRegExpr interpreteert lijnscheidingstekens zoals aanbevolen op www.unicode.org:

^ komt overeen met het begin van de invoertekst, en ook, als de modifier /m is opgenomen, met de periode onmiddellijk volgend op \x0D\x0A , \x0A of \x0D (als u de Unicode-versie gebruikt

$ komt overeen met het einde van de invoertekst en ook, als de modifier /m is opgenomen, de punt onmiddellijk voorafgaand aan \x0D\x0A , \x0A of \x0D (als u de Unicode-versie van TRegExpr gebruikt, dan ook \x2028 of \ x2029 of \x0B of \x0C of \x85). Merk op dat het niet overeenkomt binnen de reeks \x0D\x0A .

Komt overeen met elk teken, maar als de r /s-modifier is uitgeschakeld, dan. komt niet overeen met \x0D\x0A en \x0A en \x0D (als u de Unicode-versie van TRegExpr gebruikt, komt deze niet overeen met \x2028 en \x2029 en \x0B en \x0C en \x85).

Houd er rekening mee dat ^.*$ (patroon voor lege regel) komt niet overeen met de lege string van de vorm \x0D\x0A , maar wel met \x0A\x0D .

U kunt het bovenstaande gedrag opnieuw configureren bij het verwerken van tekst met meerdere regels - zie de beschrijvingen van de eigenschappen LineSeparators en LinePairedSeparator. U kunt bijvoorbeeld opnieuw configureren om alleen Unix-regelscheidingstekens \n of alleen DOS/Windows-scheidingstekens \r\n of gemengde scheidingstekens te gebruiken (of standaard geconfigureerd) of definieer zelfs uw eigen lijnscheidingstekens!

Metatekens - standaardlijsten met tekens

\w alfanumeriek teken of "_" \W niet \w \d numeriek teken \D niet \d \s elk "witruimte"-teken (standaard is [ \t\n\r\f]) \S niet \ s

De standaardlijsten \w , \d en \s kunnen ook binnen karakterlijsten worden gebruikt.

Voorbeelden:

foob\dr vindt "foob1r", ""foob6r", enz. maar niet "foobar", "foobbr", enz. foob[\w\s]r vindt "foobar", "foob r", "foobbr" enz. maar niet "foob1r", "foob=r" enz.

Metatekens - opties

U kunt een lijst met opties definiëren met behulp van het metateken | om ze te scheiden, bijvoorbeeld: fee|fie|foe zal fee of fie of foe vinden (hetzelfde als f(e|i|o)e). Als eerste optie wordt alles vanaf het vorige metateken (of [ of vanaf het begin van de uitdrukking tot het eerste metateken | gezien, als de laatste optie - alles vanaf het laatste | tot het einde van de uitdrukking of tot het dichtstbijzijnde metateken) . Om verwarring te voorkomen, staat de reeks opties doorgaans altijd tussen haakjes, ook al zou dit zonder kunnen.

Opties worden geprobeerd vanaf de eerste en pogingen worden voltooid zodra het mogelijk is er een te selecteren waarin het gehele volgende deel van de uitdrukking overeenkomt (zie het werkingsmechanisme voor meer details). Dit betekent dat varianten niet noodzakelijkerwijs tot hebzuchtig gedrag zullen leiden. Als u bijvoorbeeld de uitdrukking foo|foot toepast op de invoertekenreeks barefoot , wordt foo gevonden omdat dit de eerste optie is waarmee de gehele uitdrukking overeenkomt.

Merk op dat het metateken | wordt gezien als een gewoon teken in lijsten met tekens, het betekent bijvoorbeeld precies hetzelfde als .

Voorbeelden:

foo(bar|foo) komt overeen met "foobar" of "foofoo".

Metatekens - subexpressies

Metatekens (...) kunnen ook worden gebruikt om subexpressies te specificeren

  • Nadat u de zoekopdracht naar een uitdrukking hebt voltooid, kunt u toegang krijgen tot elke subexpressie met behulp van de eigenschappen MatchPos, MatchLen en Match, en kunt u ook subexpressies in een sjabloon vervangen met behulp van de Substitute-methode.

Subexpressies zijn genummerd van links naar rechts, in de volgorde waarin de openingshaakjes verschijnen.

De eerste subexpressie heeft nummer 1 (de gehele expressie is 0" , deze is toegankelijk via Substitute $0" of $&).

Voorbeelden:

(foobar)(8,10) vindt een string met 8, 9 of 10 kopieën van "foobar" foob(|a+)r vindt "foob0r", "foob1r", "foobar", "foobaar", "foobaar", enz. .

Metatekens - backlinks

Metatekens \1 tot en met \9 worden behandeld als backlinks. \ komt overeen met de eerder gevonden subexpressie # .

Voorbeelden:

(.)\1+ vindt "aaaa" en "cc". (.+)\1+ komt ook overeen met "abab" en "123123" ([""]?)(\d+)\1 komt overeen met "13" (tussen dubbele aanhalingstekens), of "4" (tussen enkele aanhalingstekens) of 77 (zonder aanhalingstekens), enz.

Modificatoren

Modifiers worden gebruikt om de bedrijfsmodi van TRegExpr te wijzigen.

U kunt modifiers op verschillende manieren wijzigen.

Elke modifier kan worden gewijzigd met behulp van een speciale constructie (?...) binnen een reguliere expressie.

U kunt ook een waarde toewijzen aan de overeenkomstige eigenschap van de TRegExpr-objectinstantie (bijvoorbeeld ModifierX om de modifier /x te wijzigen, of ModifierStr om meerdere modifiers tegelijk te wijzigen). Standaardwaarden voor nieuwe exemplaren van TRegExpr-objecten worden gedefinieerd in RegExprModifierX definieert bijvoorbeeld de standaardwaarde voor ModifierX.

i

Hoofdletterongevoelige modus (gebruikt standaard de standaardtaal die in het besturingssysteem is geselecteerd), (zie ook InvertCase)

M

S

G

Geen standaard modificatie. Door het uit te schakelen, zet je alle repeaters in de “niet-hebzuchtige” modus (deze modifier is standaard ingeschakeld). Die. Als je het uitschakelt, werken alle + dan als +? , * Hoe *? enz.

X

Hiermee kunt u de sjabloon opmaken zodat deze gemakkelijker leesbaar is (zie onderstaande beschrijving).

R

Geen standaard modificatie. Indien ingeschakeld, dan bereiken typ a-z bevat ook de letter ё, A-Z omvat Ё en a-Z omvat in het algemeen alle Russische letters.

De modifier /x zorgt ervoor dat TRegExpr spaties, tabs en regelscheidingstekens negeert, waardoor de tekst van de expressie kan worden opgemaakt. Als bovendien het #-teken wordt aangetroffen, worden alle daaropvolgende tekens tot het einde van de regel behandeld als commentaar, bijvoorbeeld:

((abc) # Commentaar 1 | # Spaties binnen de uitdrukking worden ook genegeerd (efg) # Commentaar 2)

Dit betekent uiteraard dat als u een spatie, tab of regelscheidingsteken of # in een uitdrukking moet invoegen, dit in de uitgebreide (/x) modus alleen kan worden gedaan door ze vooraf te laten gaan door / of door /xnn te gebruiken (binnen tekenlijsten , al deze karakters worden zoals gewoonlijk behandeld)

Perl-extensies

(?imsxr-imsxr)

Hiermee kunt u modificatiewaarden wijzigen

Voorbeelden:

(?i)Sint-Petersburg vindt "Sint-Petersburg" en "Sint-Petersburg" (?i)Sint-(?-i)Petersburg vindt "Sint-Petersburg" maar niet "Sint-Petersburg" (?i)(Sint-Petersburg -)?Petersburg vindt "Sint-Petersburg" en "Sint-Petersburg" ((?i)Sint-)?Petersburg vindt "Sint-Petersburg", maar niet "Sint-Petersburg"

Het spiekbriefje is een algemene gids voor reguliere expressiepatronen zonder rekening te houden met de specifieke kenmerken van welke taal dan ook. Het wordt gepresenteerd in de vorm van een tabel die op één bedrukt vel A4-formaat past. Gemaakt onder een Creative Commons-licentie, gebaseerd op een spiekbriefje geschreven door Dave Child ().

Houd er rekening mee dat verschillende programmeertalen reguliere expressies ondersteunen verschillende graden, waardoor u mogelijk een situatie tegenkomt waarin sommige van de genoemde functies niet werken. Voor degenen die net kennis maken met reguliere expressies, wordt deze vertaling van de opmerkingen van de auteur op het spiekbriefje aangeboden. Het laat je kennismaken met enkele van de technieken die worden gebruikt bij het bouwen van reguliere expressiepatronen.

Ankers in reguliere expressies geven het begin of einde van iets aan. Bijvoorbeeld lijnen of woorden. Ze worden weergegeven door bepaalde symbolen. Een patroon dat overeenkomt met een tekenreeks die begint met een getal, ziet er bijvoorbeeld als volgt uit:

Hier geeft het ^-symbool het begin van de regel aan. Zonder dit zou het patroon overeenkomen met elke string die een cijfer bevat.

Tekenklassen in reguliere expressies komen in één keer overeen met een bepaalde reeks tekens. \d komt bijvoorbeeld overeen met elk getal van 0 tot en met 9, \w komt overeen met letters en cijfers, en \W komt overeen met alle tekens behalve letters en cijfers. Het patroon dat letters, cijfers en spaties identificeert, ziet er als volgt uit:

POSIX

POSIX is een relatief nieuwe toevoeging aan de reguliere expressiefamilie. Het idee is, net als bij tekenklassen, om snelkoppelingen te gebruiken die een bepaalde groep tekens vertegenwoordigen.

Bijna iedereen heeft in het begin moeite met het begrijpen van affirmaties, maar naarmate je er meer vertrouwd mee raakt, zul je merken dat je ze vrij vaak gebruikt. Beweringen bieden een manier om te zeggen: 'Ik wil elk woord in dit document vinden dat de letter 'q' bevat en niet wordt gevolgd door 'werty'.

[^\s]*q(?!werty)[^\s]*

De bovenstaande code begint met het zoeken naar andere tekens dan spatie ([^\s]*), gevolgd door q . De parser komt dan tot een toekomstgerichte bewering. Hierdoor wordt het voorgaande element (teken, groep of tekenklasse) automatisch voorwaardelijk gemaakt: het komt alleen overeen met het patroon als de bewering waar is. In ons geval is de verklaring negatief (?!), dat wil zeggen dat hij waar zal zijn als wat erin wordt gezocht, niet wordt gevonden.

De parser controleert dus de volgende paar tekens aan de hand van het voorgestelde patroon (werty). Als ze worden gevonden, is de verklaring onwaar, wat betekent dat het teken q wordt “genegeerd”, dat wil zeggen dat het niet overeenkomt met het patroon. Als werty niet wordt gevonden, is de bewering waar en is alles in orde met q. Vervolgens gaat het zoeken verder naar alle andere tekens dan spatie ([^\s]*).

Deze groep bevat voorbeeldsjablonen. Met hun hulp kun je zien hoe reguliere expressies in de dagelijkse praktijk kunnen worden gebruikt. Houd er echter rekening mee dat ze niet noodzakelijkerwijs in elke programmeertaal zullen werken, aangezien elk van hen dat wel doet individuele kenmerken en verschillende niveaus van ondersteuning voor reguliere expressies.

Met kwantoren kunt u een deel van een patroon definiëren dat meerdere keren achter elkaar moet worden herhaald. Als u bijvoorbeeld wilt weten of een document een reeks van 10 tot 20 (inclusief) letters "a" bevat, kunt u dit patroon gebruiken:

EEN(10,20)

Kwantificeerders zijn standaard ‘hebzuchtig’. Daarom komt de kwantor +, wat 'een of meerdere keren' betekent, overeen met de maximaal mogelijke waarde. Soms veroorzaakt dit problemen, in welk geval je de kwantor kunt vertellen niet langer hebzuchtig te zijn ('lui' te worden) door een speciale modificator te gebruiken. Kijk naar deze code:

".*"

Dit patroon komt overeen met tekst tussen dubbele aanhalingstekens. Uw bronregel kan er echter ongeveer zo uitzien:

Hallo Wereld

De bovenstaande sjabloon vindt de volgende subtekenreeks in deze regel:

"helloworld.htm" title="Hallo wereld" !}

Hij bleek te hebzuchtig en pakte het grootste stuk tekst dat hij kon.

".*?"

Dit patroon komt ook overeen met alle tekens tussen dubbele aanhalingstekens. Maar de luie versie (let op de modifier?) zoekt naar de kleinst mogelijke gebeurtenis en zal daarom elke substring vinden dubbele aanhalingstekens afzonderlijk:

"Hallowereld.htm" "Hallo wereld"

Reguliere expressies gebruiken bepaalde tekens om verschillende delen van een patroon weer te geven. Er doet zich echter een probleem voor als u een van deze tekens in een string moet vinden, net als een gewoon teken. Een punt in een reguliere expressie betekent bijvoorbeeld ‘elk teken, behalve een regeleinde’. Als je een punt in een string wilt vinden, kun je niet zomaar " gebruiken. ' als sjabloon - dit zal ertoe leiden dat u bijna alles kunt vinden. U moet de parser dus vertellen dat deze punt als een gewone punt moet worden beschouwd en niet als "een teken". Dit gebeurt met behulp van het ontsnappingsteken.

Een escape-teken dat voorafgaat aan een teken, zoals een punt, zorgt ervoor dat de parser de functie ervan negeert en het als een normaal teken behandelt. Er zijn verschillende karakters die in de meeste sjablonen en talen een dergelijke ontsnapping vereisen. Je kunt ze vinden in de rechter benedenhoek van het spiekbriefje (“Metasymbolen”).

Het patroon voor het vinden van een punt is:

\.

Andere speciale tekens in reguliere expressies komen overeen met ongebruikelijke elementen in de tekst. Regeleinden en tabs kunnen bijvoorbeeld op het toetsenbord worden getypt, maar veroorzaken waarschijnlijk verwarring bij programmeertalen. Het escape-teken wordt hier gebruikt om de parser te vertellen het volgende teken als speciaal te behandelen in plaats van een gewone brief of nummer.

Stringvervanging wordt in detail beschreven in de volgende paragraaf, “Groepen en bereiken”, maar het bestaan ​​van “passieve” groepen moet hier worden vermeld. Dit zijn groepen die tijdens de vervanging worden genegeerd, wat erg handig is als u een 'of'-voorwaarde in een patroon wilt gebruiken, maar niet wilt dat die groep deelneemt aan de vervanging.

Groepen en bereiken zijn heel erg handig. Het is waarschijnlijk gemakkelijker om met bereiken te beginnen. Hiermee kunt u een reeks geschikte tekens opgeven. Als u bijvoorbeeld wilt controleren of een string hexadecimale cijfers bevat (0 t/m 9 en A t/m F), gebruikt u het volgende bereik:

Om het tegenovergestelde te controleren, gebruikt u een negatief bereik, dat in ons geval op elk teken past, behalve cijfers van 0 tot 9 en letters van A tot F:

[^A-Fa-f0-9]

Groepen worden het vaakst gebruikt als er een 'of'-voorwaarde nodig is in een patroon; wanneer u vanuit een ander deel naar een deel van een sjabloon moet verwijzen; en ook bij het vervangen van strings.

Het gebruik van "or" is heel eenvoudig: het volgende patroon zoekt naar "ab" of "bc":

Als het in een reguliere expressie nodig is om naar een van de voorgaande groepen te verwijzen, moet u \n gebruiken, waarbij u in plaats van n het getal vervangt de gewenste groep. Misschien wilt u een patroon dat overeenkomt met de letters "aaa" of "bbb", gevolgd door een cijfer en vervolgens dezelfde drie letters. Dit patroon wordt geïmplementeerd met behulp van groepen:

(aaa|bbb)+\1

Het eerste deel van het patroon zoekt naar "aaa" of "bbb", waarbij de gevonden letters in een groep worden gecombineerd. Dit wordt gevolgd door een zoektocht naar een of meer cijfers (+), en tenslotte \1. Het laatste deel van het patroon verwijst naar de eerste groep en zoekt naar hetzelfde. Er wordt gezocht naar een overeenkomst met de tekst die al in het eerste deel van het patroon is gevonden, en niet naar een overeenkomst daarmee. Dus "aaa123bbb" voldoet niet aan het bovenstaande patroon, omdat \1 na het nummer naar "aaa" zal zoeken.

Een van de meest nuttige hulpmiddelen in reguliere expressies is tekenreeksvervanging. Wanneer u tekst vervangt, kunt u naar de gevonden groep verwijzen met $n . Stel dat u alle woorden 'wens' in een tekst vetgedrukt wilt markeren. Om dit te doen, moet u een vervangingsfunctie voor reguliere expressies gebruiken, die er als volgt uit kan zien:

Vervangen(patroon, vervanging, onderwerp)

De eerste parameter zal er ongeveer zo uitzien (mogelijk heb je een paar extra tekens nodig voor deze specifieke functie):

([^A-Za-z0-9])(wens)([^A-Za-z0-9])

Het zal alle voorkomens van het woord "wens" vinden, samen met de vorige en volgende tekens, zolang het maar geen letters of cijfers zijn. Dan zou je vervanging er als volgt uit kunnen zien:

$1$2$3

Het zal de volledige string vervangen die met behulp van het patroon is gevonden. We beginnen te vervangen door het eerste gevonden teken (dat geen letter of cijfer is), en markeren het $1 . Zonder dit zouden we dit teken eenvoudigweg uit de tekst verwijderen. Hetzelfde geldt voor het einde van de vervanging ($3). In het midden hebben we toegevoegd HTML-tag voor vetgedrukt (je kunt natuurlijk CSS of ), waardoor ze de tweede groep worden toegewezen die is gevonden met behulp van de sjabloon ($ 2).

Sjabloonmodifiers worden in verschillende talen gebruikt, met name in Perl. Hiermee kunt u de manier wijzigen waarop de parser werkt. De i-modifier zorgt er bijvoorbeeld voor dat de parser gevallen negeert.

Reguliere expressies in Perl worden aan het begin en aan het einde omgeven door hetzelfde teken. Dit kan elk teken zijn (meestal wordt “/” gebruikt) en het ziet er als volgt uit:

/patroon/

Modifiers worden als volgt aan het einde van deze regel toegevoegd:

/patroon/ik

Ten slotte bevat het laatste deel van de tabel metatekens. Dit zijn tekens die een speciale betekenis hebben in reguliere expressies. Dus als je een van deze als een gewoon personage wilt gebruiken, moet deze worden geëscaped. Gebruik het volgende patroon om te controleren of er haakjes in de tekst voorkomen:

Echt bedankt. vooral voor de verduidelijking. Graag gedaan :) Hartelijk dank. ontzettend bedankt! Bedankt Coole serie... trouwens, ik vertaal deze serie vanuit het Engels (en doe het in HTML-formaat), je kunt hem bekijken op mijn website: sitemaker.x10.bz. Er is ook een spiekbriefje over HTML, dat is hier niet. Bedankt. Hoe zit het met het verwijderen van de eerste 10 tekens van welke aard dan ook, en dan zal er wat tekst zijn met symbolen, en dan met een bepaald karakter Het zal nodig zijn om alles volledig te verwijderen. !? 2 lails: Reguliere expressies zijn hier niet nodig. Substr() en strpos() zullen je helpen als we het hebben over PHP, of hun analogen in andere talen. Het was interessant om over de uitspraken te lezen, ik begin het langzamerhand te begrijpen. Op deze manier zal het duidelijker zijn: http://pcreonline.com/OazZNu/ Hallo. Kunt u mij vertellen waarom “achterwaarts gerichte uitspraken” bij mij niet werken in FireFox? Mozilla's RegExp-hulp heeft ze helemaal niet. Is het echt onmogelijk in Fox? =((( Goedemorgen, achterwaarts gerichte uitspraken worden niet ondersteund door JavaScript, dus naar alle waarschijnlijkheid zullen ze ook niet werken in andere browsers. Er staat meer op deze link gedetailleerde informatie over de beperkingen van reguliere expressies in JavaScript. Goed gedaan! geef mij een high five! Bedankt! Kort en duidelijk! Hm. Dank u dank u! bedankt, het heeft enorm geholpen, heel erg bedankt! Bedankt voor het artikel! Vertel me eens, wat als u de wachtwoordinvoer moet beperken tot cijfers en niet meer dan vijf letters? Hallo, het spiekbriefje is goed voor iedereen, maar het zou mogelijk zijn om de zebra lichter te maken, want als je zwarte letters afdrukt donkere achtergrond niet erg bedankt. Een kleine vraag: u moet de waarden tussen start= en & vinden, maar tegelijkertijd deze bereikgrenzen uitsluiten van de uitvoer. Hoe u het voltooide bereik kunt vinden: start=.(1,)&
Maar er is nog steeds niet genoeg kennis over hoe grenzen kunnen worden opgeheven. Ik zou dankbaar zijn voor uw hulp. Kunt u mij vertellen hoe ik een reguliere expressie kan instellen om te controleren (er kan wel of geen overeenkomst zijn)? Hoe u op de juiste manier een reguliere expressie schrijft die begint met het gelijkteken, de tekst erin vindt en stopt bij het &-teken
Deze karakters zijn niet opgenomen in de zoekopdracht die ermee begint en eindigt noodzakelijk onderdeel lijnen...

Ik schrijf op verschillende manieren, maar als resultaat blijft de hele tekst behouden, maar verdwijnen de = en & tekens
Of blijft de & aan het einde van de regel...
Ik las over de dollar, maar het teken aan het einde van de regel wordt niet verwijderd

klein voorbeeld

var reg = /[^=]*[^&]/g
str.match(reg);

Logischerwijs beginnen we met het gelijkteken en zoeken we naar tekst /[^=]*
dan stoppen we bij het bord & [^&] zonder het op te nemen in de zoekopdracht en herhalen we de zoekopdracht langer totdat we er volledig omheen gaan /g

Werkt niet... Geeft de volledige tekenreeks terug

Goedenavond, vertel me hoe ik een getal kan vinden dat kleiner is dan 20? Bedankt jongens Bedankt voor het artikel! Vertel me eens, wat als u de wachtwoordinvoer moet beperken tot cijfers en niet meer dan vijf letters?

Dima @ 24 april 2015
Antwoord:((?=.*\d)(?=.*)(?=.*).(8,15))--- zet aan het einde, in plaats van 8, gewoon 5

Hallo allemaal, Ik ben net begonnen...
Kunt u mij vertellen wat het betekent:
/^\w\w/a
Ik zou je heel dankbaar zijn) Hallo, vertel me hoe ik alle cijfers in moet vermelden deze uitdrukking door de ruimte 9*2 Goddelijk spiekbriefje! Alle vragen opgelost :-) (M1)
(M2)
(M3)
(M4)
(M5)

Vertel me hoe ik een uitdrukking moet schrijven om te achterhalen waar deze in de tekst voorkomt

Wat zijn reguliere expressies?

Als je ooit mee hebt moeten werken opdrachtregel, hebt u waarschijnlijk bestandsnaammaskers gebruikt. Als u bijvoorbeeld alle bestanden in de huidige map wilt verwijderen die beginnen met de letter "d", kunt u schrijven

Reguliere expressies zijn een soortgelijk, maar veel krachtiger hulpmiddel voor het vinden van tekenreeksen, het testen ervan aan de hand van een patroon en ander soortgelijk werk. De Engelse naam van dit instrument is Normale uitdrukkingen of gewoon RegExp. Strikt genomen zijn reguliere expressies een speciale taal voor het beschrijven van tekenreekspatronen.

De implementatie van deze tool varieert afhankelijk van verschillende talen programmeren, hoewel niet veel. In dit artikel zullen we ons vooral concentreren op de implementatie van Perl-compatibele reguliere expressies.

Basisbeginselen van syntaxis

Allereerst is het vermeldenswaard dat elke string zelf een reguliere expressie is. De uitdrukking dus

Haha komt uiteraard overeen met de string "Haha" en alleen dat. Reguliere expressies zijn hoofdlettergevoelig, dus de tekenreeks "haha" (kleine letters) komt niet langer overeen met de bovenstaande expressie.

U moet hier echter voorzichtig zijn: zoals elke taal hebben reguliere expressies speciale tekens die moeten worden geëscaped. Hier is hun lijst:

. ^ $ * + ? ( ) \ | (). Er wordt afscherming uitgevoerd op de gebruikelijke manier- \ toevoegen vóór het speciale teken.

Karakterset

Stel dat we in een tekst alle tussenwerpsels willen vinden die op gelach duiden. Zojuist

Haha past niet bij ons - "Hehe", "Hoho" en "Hihi" vallen er immers niet onder. En het probleem met de eerste letter moet op de een of andere manier worden opgelost.

Hier komen sets ons te hulp - in plaats van een specifiek karakter te specificeren, kunnen we een hele lijst opschrijven, en als de regel die wordt onderzocht opgegeven locatie een van de genoemde tekens zal zijn, wordt de string als geschikt beschouwd. Sets staan ​​tussen vierkante haakjes - patroon

Komt overeen met elk van de tekens "a", "b", "c" of "d".

Binnenset b O De meeste speciale tekens hoeven niet te worden geëscaped, maar moeten worden gebruikt

\ die ervoor staat, wordt niet als een fout beschouwd. Het is nog steeds nodig om de tekens “\” en “^” te escapen, en bij voorkeur “]” (het betekent dus een van de tekens “]” of “[”, terwijl [x] uitsluitend de reeks “[ is X]"). Het ogenschijnlijk ongebruikelijke gedrag van reguliere expressies met het teken “]” wordt feitelijk bepaald door bekende regels, maar het is veel gemakkelijker om eenvoudigweg aan dit teken te ontsnappen dan om ze te onthouden. Bovendien moet het “-”-symbool worden geëscaped; dit wordt gebruikt om bereiken in te stellen (zie hieronder).

Indien onmiddellijk daarna

[schrijf het symbool ^ op, dan krijgt de set de tegenovergestelde betekenis - elk ander symbool dan de aangegeven symbolen wordt als geschikt beschouwd. Het patroon [^xyz] komt dus overeen met elk teken behalve “x”, “y” of “z”.

Gebruiken dus dit hulpmiddel voor onze zaak, als we schrijven

[Xx][aoie]x[aoie] , dan zal elk van de regels “Haha”, “hehe”, “hihi” en zelfs “Hoho” overeenkomen met het patroon.

Vooraf gedefinieerde tekenklassen

Voor sommige sets die vrij vaak worden gebruikt, zijn er speciale sjablonen. Dus om er een te beschrijven witruimte karakter(spatie, tab, regeleinde) wordt gebruikt

\s , voor cijfers - \d , voor Latijnse tekens, cijfers en onderstrepingstekens "_" - \w .

Als het überhaupt nodig is om een ​​teken te beschrijven, wordt hiervoor een punt gebruikt -

Als de opgegeven klassen met een hoofdletter (\S , \D , \W) worden geschreven, veranderen ze hun betekenis in het tegenovergestelde: elk teken dat geen witruimte bevat, elk teken dat geen getal is en elk ander teken dan het Latijns alfabet, cijfers of onderstrepingstekens, respectievelijk.

Met reguliere expressies is het ook mogelijk om de positie van een regel ten opzichte van de rest van de tekst te controleren. Uitdrukking

\b geeft een woordgrens aan, \B is een niet-woordgrens, ^ is het begin van de tekst en $ is het einde. Dus volgens het \bJava\b-patroon worden de eerste 4 tekens gevonden in de regel “Java en JavaScript”, en volgens het \bJava\B-patroon worden de 10e tot en met 13e tekens gevonden (als onderdeel van de woord “JavaScript”).

Bereiken

Mogelijk moet u een set aanwijzen die letters bevat, bijvoorbeeld van "b" tot "f". In plaats van schrijven

[bvgdezziklmnoprstuf] je kunt het bereikmechanisme gebruiken en schrijven [b-f] . Patroon x komt dus overeen met de string “xA6”, maar niet met “xb9” (in de eerste plaats vanwege het feit dat alleen hoofdletters ten tweede vanwege het feit dat 9 niet is opgenomen in het bereik 0-8).

Het bereikmechanisme is vooral relevant voor de Russische taal, omdat er geen soortgelijke constructie voor bestaat

\ w . Om alle letters van het Russische alfabet aan te duiden, kunt u het patroon [а-яА-ЯеО] gebruiken. Houd er rekening mee dat de letter “е” niet is opgenomen in het algemene letterbereik en apart moet worden gespecificeerd.

Kwantificatoren (die het aantal herhalingen aangeven)

Laten we terugkeren naar ons voorbeeld. Wat als het 'lachende' tussenwerpsel meer dan één klinker tussen de x's had, zoals 'Haahaaaa'? Ons oude reguliere seizoen gaat ons niet meer kunnen helpen. Hier zullen we kwantificatoren moeten gebruiken.

Merk op dat de kwantor alleen van toepassing is op het teken dat ervoor staat.

Sommige veelgebruikte constructies hebben speciale notaties gekregen in de reguliere expressietaal:

Dus met behulp van kwantoren kunnen we ons patroon voor tussenwerpsels verbeteren

[Xx][aoee]+x[aoee]* , en het zal de regels "Haaha", "heeeeeh" en "Hihii" kunnen herkennen.

Luie kwantificering

Stel dat we voor de taak staan ​​om alle HTML-tags in een string te vinden

Tproger- Mijn Liefje website over programmeren!

De voor de hand liggende oplossing

<.*>het zal hier niet werken - het zal de hele string vinden, omdat het begint met en eindigt met een alineatag. Dat wil zeggen dat de inhoud van de tag wordt beschouwd als de tekenreeks p> Tproger- Mijn Liefje website over programmeren!

Dit gebeurt vanwege het feit dat de kwantificator standaard werkt volgens de zogenaamde. hebberig algoritme - probeert de langst mogelijke tekenreeks terug te geven die aan de voorwaarde voldoet. Er zijn twee manieren om het probleem op te lossen. De eerste is om de uitdrukking te gebruiken

<[^>]*> , waardoor wordt voorkomen dat het haakse haakje wordt beschouwd als de inhoud van de tag. De tweede is om de kwantor niet hebzuchtig te verklaren, maar lui. Wordt dit gedaan door rechts van de tekenkwantificator toe te voegen? . Die. om naar alle tags te zoeken, zal de expressie veranderen naar<.*?> .

Jaloerse kwantificering

Om de zoeksnelheid te verhogen (vooral in gevallen waarin de tekenreeks niet overeenkomt met de reguliere expressie), kunt u soms voorkomen dat het algoritme teruggaat naar eerdere zoekstappen om mogelijke overeenkomsten voor de rest van de reguliere expressie te vinden. Het heet jaloers kwantificering. De kwantor wordt jaloers gemaakt door het symbool rechts ervan toe te voegen

Een ander gebruik van jaloerse kwantificering is het uitsluiten van ongewenste matches. Het patroon ab*+a in de string “ababa” komt dus alleen overeen met de eerste drie karakters, maar niet met de karakters van het derde tot en met het vijfde, omdat het teken "a", dat op de derde positie staat, is al gebruikt voor het eerste resultaat.

Beugelgroepen

Voor ons ‘lachende’ tussenwerpselsjabloon is het enige kleine dat we nog moeten doen, rekening houden met het feit dat de letter ‘x’ meer dan één keer kan voorkomen, bijvoorbeeld ‘Hahahahaaahaahoooo’, en zelfs kan eindigen met de letter ‘x’. Waarschijnlijk moet u hier een groepskwantificator toepassen

[aioe]+x, maar als we alleen [aioe]x+ schrijven, dan is de kwantor + alleen van toepassing op het teken “x” en niet op de hele uitdrukking. Om dit op te lossen moet de expressie tussen haakjes worden geplaatst: ([aioe]x)+ .

Zo wordt onze expressie

[Xx]([aioe]x?)+ - eerst is er een hoofdletter of kleine letter “x”, en dan een willekeurig aantal klinkers dat niet nul is, die (mogelijk, maar niet noodzakelijkerwijs) worden afgewisseld met een enkele kleine letter “x” . Deze uitdrukking lost het probleem echter slechts gedeeltelijk op - deze uitdrukking zal ook regels bevatten zoals bijvoorbeeld "hihaheh" - iemand kan zo lachen, maar de veronderstelling is zeer twijfelachtig. Het is duidelijk dat we een verzameling van alle klinkers maar één keer kunnen gebruiken, en dan moeten we op de een of andere manier vertrouwen op het resultaat van de eerste zoekopdracht. Maar hoe?…

Het zoekresultaat per groep onthouden (feedback)

Het blijkt dat het resultaat van een zoekopdracht naar een haakjesgroep naar een afzonderlijke geheugencel wordt geschreven, die toegankelijk is voor gebruik in volgende delen van de reguliere expressie. Terugkomend op de taak om HTML-tags op een pagina te vinden, moeten we misschien niet alleen de tags vinden, maar ook hun naam achterhalen. Een reguliere expressie kan ons hierbij helpen

<(.*?)> .

Tproger- Mijn Liefje website over programmeren!

Zoekresultaat voor alle reguliere expressies: "

», « », «», « », «», «

».
Zoekresultaat voor de eerste groep: “p”, “b”, “/b”, “i”, “/i”, “/i”, “/p”.

Er kan naar het resultaat van een groepszoekopdracht worden verwezen met behulp van de expressie

\n , waarbij n een getal is van 1 tot en met 9. De uitdrukking (\w)(\w)\1\2 komt bijvoorbeeld overeen met de tekenreeksen “aaaa”, “abab”, maar komt niet overeen met “aabb”.

Als een uitdrukking alleen tussen haakjes wordt geplaatst om er een kwantor op toe te passen (er zijn geen plannen om het zoekresultaat voor deze groep te onthouden), dan moet het eerste haakje onmiddellijk worden toegevoegd

?: , bijvoorbeeld (?:+\w) .

Met behulp van dit mechanisme kunnen we onze uitdrukking naar de vorm herschrijven

[Xx]([aoie])x?(?:\1x?)* .

Overdracht

Om te controleren of een string aan ten minste één van de patronen voldoet, kunt u een analoog van de Booleaanse operator OR gebruiken, die is geschreven met het symbool

| . Het Anna|Eenzaamheid-patroon bevat dus respectievelijk de regels “Anna” en “Eenzaamheid”. Het is vooral handig om opsommingen tussen haakjesgroepen te gebruiken. Dus bijvoorbeeld (?:a|b|c|d) is volledig equivalent (in in dit geval de tweede optie verdient de voorkeur vanwege prestaties en leesbaarheid).

Met behulp van deze operator kunnen we aan onze reguliere expressie voor het vinden van tussenwerpsels het vermogen toevoegen om lachjes als "Ahahaah" te herkennen - de enige glimlach die begint met een klinker:

[Xx]([aoie])x?(?:\1x?)*|[Aa]x?(?:ah?)+

Nuttige diensten

U kunt uw reguliere expressie op bepaalde tekst oefenen en/of testen zonder code te schrijven met behulp van services zoals RegExr, Regexpal of Regex101. Deze laatste geeft bovendien korte uitleg over hoe het reguliere systeem werkt.

U kunt erachter komen hoe een reguliere expressie die u in handen krijgt, werkt met behulp van de Regexper-service - deze kan begrijpelijke diagrammen maken met behulp van een reguliere expressie.

RegExp Builder - visuele constructor JavaScript-functies voor het werken met reguliere expressies.

0

0