Dit is een naslagwerk – lees het niet te veel, want het is nogal beknopt. Andere secties linken ernaar wanneer nodig.
Regex modifiers duiken op deze site op elke hoek op. Liever dan herhaaldelijk uit te leggen wat ze doen en de vele manieren om ze aan te zetten in elke regex smaak, heb ik besloten om de vier meest voorkomende (i, s, m en x) op een plaats te verzamelen. De laatste sectie geeft een kort overzicht van andere modifiers, die meestal taal-specifiek zijn.
Punten
Voor een gemakkelijke navigatie zijn hier enkele punten om naar de verschillende secties van de pagina te springen:
✽ Hoofdlettergevoeligheid: i
✽ DOTALL (Dot Matches Line Breaks): s (behalve Ruby en JavaScript)
✽ Multiline (^ en $ komen overeen op elke regel): m (behalve Ruby)
✽ Free-Spacing: x (behalve JavaScript)
✽ Other Modifiers
✽ PCRE’s Special Start-of-Pattern Modifiers
(directe link)
Case Insensitivity: i
Alle grote regex engines matchen standaard in hoofdlettergevoelige modus. Als u patronen zoals Naam: + hoofdletterongevoelig overeenkomen, moeten we die functie inschakelen.
Ja, maar…
Wat betekent hoofdletterongevoelig eigenlijk?
Zolang u zich houdt aan de 26 letters van het Engelse alfabet, is de definitie van hoofdletters en kleine letters rechttoe rechtaan. Wanneer u zich echter gaat bezighouden met typografische finesses of andere talen en schriften, liggen de zaken niet altijd even eenvoudig. Hier zijn enkele vragen die u kunt tegenkomen.
✽ Zal fl (één teken, d.w.z. de ligatuur fl) overeenkomen met FL?
✽ Zal à (één teken) overeenkomen met À?
✽ Zal à (twee tekens, d.w.z. de letter a en het accent grave) overeenkomen met À? Alle engines lijken dat correct te verwerken.
✽ Komt ß overeen met ss? Geen enkele machine lijkt dat te doen.
✽ Zal i overeenkomen met İ (Turkse hoofdletter i) en ook met I?
Deze vragen zijn slechts het topje van de ijsberg. Zelfs als ik alle antwoorden wist, zou het onmogelijk zijn om ze allemaal in deze sectie op te nemen: als u een bepaald script gebruikt, zult u moeten onderzoeken hoe uw specifieke engine omgaat met hoofdlettergevoelige koppeling in dat script.
Meer dan één manier
Voor verschillende engines zijn er twee manieren om hoofdlettergevoelige koppeling aan te zetten: als een inline modifier (?i) of als een optie in de regex methode of functie.
Inline Modifier (?i)
In .NET, PCRE (C, PHP, R…), Perl, Python, Java en Ruby (maar niet JavaScript), kunt u de inline modifier (?i) gebruiken, bijvoorbeeld in (?i)cat. Zie de sectie over inline modifiers voor sappige details over drie extra functies (niet beschikbaar in Python): midden in de string aanzetten, uitzetten met (?-i), of alleen toepassen op de inhoud van een niet-capture groep met (?i:foo)
.NET
Naast de (?i) inline modifier, hebben .NET talen de IgnoreCase optie. In C# kunt u bijvoorbeeld gebruiken:var catRegex = new Regex("cat", RegexOptions.IgnoreCase);
Perl
Naast de (?i) inline-modifier kunt u in Perl de vlag i toevoegen na het scheidingsteken waarmee uw patroon wordt afgesloten. Je kunt bijvoorbeeld gebruiken:if ($the_subject =~ m/cat/i) { … }
PCRE (C, PHP, R…)
Merk op dat in PCRE, om hoofdletterongevoelige matching te gebruiken met niet-Engelse letters die geen deel uitmaken van je locale, je de Unicode-modus moet inschakelen-bijvoorbeeld met de (*UTF8) speciale start-van-patroon modifier.
Afgezien van de (?i) inline modifier, kun je met PCRE de PCRE_CASELESS mode instellen bij het aanroepen van de pcre_compile() (of vergelijkbare) functie:
cat_regex = pcre_compile( "cat", PCRE_CASELESS, &error, &erroroffset, NULL );
In PHP wordt de PCRE_CASELESS optie doorgegeven via de i flag, die je in je regex string kunt toevoegen na de afsluitende delimiter. U kunt bijvoorbeeld gebruiken:$cat_regex = '~cat~i';
In R wordt de PCRE_CASELESS optie doorgegeven via de ignore.case=TRUE optie. U kunt bijvoorbeeld gebruiken:grep("cat", subject, perl=TRUE, value=TRUE, ignore.case=TRUE);
Python
Naast de (?i) inline-modifier heeft Python de optie IGNORECASE. U kunt bijvoorbeeld gebruiken:cat_regex = re.compile("cat", re.IGNORECASE)
Java
Naast de (?i) inline-modifier heeft Java de optie CASE_INSENSITIVE. U kunt bijvoorbeeld gebruiken:
Pattern catRegex = Pattern.compile( "cat", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE );
De hier toegevoegde optie UNICODE_CASE zorgt ervoor dat de functie voor hoofdlettergevoeligheid Unicode-bewust is. Als u alleen met ASCII werkt, hoeft u deze optie niet te gebruiken.
JavaScript
In JavaScript is uw enige optie de vlag i toe te voegen na het afsluitende scheidingsteken van uw patroon. U kunt bijvoorbeeld gebruiken:var catRegex = /cat/i;
Ruby
Naast de (?i) inline-modifier kunt u in Ruby ook de i-vlag toevoegen na het scheidingsteken waarmee het patroon wordt afgesloten. U kunt bijvoorbeeld gebruiken:cat_regex = /cat/i
(directe link)
DOTALL (punt komt overeen met regeleindes): s (met uitzonderingen)
De punt . komt standaard niet overeen met regeleindes, zoals line feeds en carriage returns. Als u patronen zoals BEGIN .*? END over regels heen overeenkomen, moeten we die functie aanzetten.
Deze modus wordt soms één regel genoemd (vandaar de s), omdat wat de punt betreft, het de hele tekenreeks in één grote regel verandert-.* zal overeenkomen van het eerste teken tot het laatste, ongeacht hoeveel regeleinden er tussen staan.
De modus wordt ook wel DOTALL genoemd in PCRE, Python en Java (om precies te zijn, de PCRE documentatie gebruikt PCRE_DOTALL). Voor mij is de naam DOTALL een zinnige manier om deze mode te noemen. De derde optie dot-matches-line-breaks is beschrijvend, maar een beetje een mond vol.
Voor verschillende engines, merk op dat er twee manieren zijn om het aan te zetten: als een inline modifier of als een optie in de regex methode of functie.
JavaScript
JavaScript ondersteunt de single-line mode niet. Om overeen te komen met elk karakter in JavaScript, inclusief regeleinden, gebruik een constructie zoals . Deze tekenklasse komt overeen met één teken dat ofwel een niet-cijferig teken ofwel een cijfer is. Daarom komt het overeen met elk teken.
Een andere JavaScript oplossing is het gebruik van de XRegExp regex library. Als je oneindig veel tijd hebt, kun je ook proberen PCRE te porten naar JavaScript met Emscripten, zoals Firas schijnt te hebben gedaan op regex 101.
Inline Modifier (?s)
In .NET, PCRE (C, PHP, R…), Perl, Python en Java (maar niet Ruby), kun je de inline modifier (?s) gebruiken, bijvoorbeeld in (?s)BEGIN .*? END. Zie de sectie over inline modifiers voor sappige details over drie extra functies (niet beschikbaar in Python): midden in de string aanzetten, uitzetten met (?-s), of alleen toepassen op de inhoud van een niet-capture groep met (?s:foo)
.NET
Afgezien van de (?s) inline modifier, hebben .NET talen de Singleline optie. In C# kunt u bijvoorbeeld gebruiken:
var blockRegex = new Regex( "BEGIN .*? END", RegexOptions.IgnoreCase | RegexOptions.Singleline );
Perl
Naast de (?s) inline-modifier kunt u in Perl ook de vlag s toevoegen na het scheidingsteken waarmee uw patroon wordt afgesloten. Bijvoorbeeld, je kunt gebruiken:if ($the_subject =~ m/BEGIN .*? END/s) { … }
PCRE (C, PHP, R…)
Naast de (?s) inline-modifier kunt u met PCRE de PCRE_DOTALL-modus instellen wanneer u de functie pcre_compile() (of een vergelijkbare functie) aanroept:
block_regex = pcre_compile( "BEGIN .*? END", PCRE_DOTALL, &error, &erroroffset, NULL );
In PHP wordt de PCRE_DOTALL-optie doorgegeven via de s-vlag, die u in uw regexstring kunt toevoegen na het afsluitende scheidingsteken. U kunt bijvoorbeeld gebruiken:$block_regex = '~BEGIN .*? END~s';
Python
Naast de (?s) inline modifier, heeft Python de DOTALL optie. U kunt bijvoorbeeld het volgende gebruiken:block_regex = re.compile("BEGIN .*? END", re.IGNORECASE | re.DOTALL)
Java
Naast de (?s) inline-modifier heeft Java de DOTALL-optie. Zo kunt u bijvoorbeeld:
Pattern blockRegex = Pattern.compile( "BEGIN .*? END", Pattern.CASE_INSENSITIVE | Pattern.DOTALL );
Ruby: (?m) modifier and m flag
In Ruby kunt u de inline modifier (?m) gebruiken, bijvoorbeeld in (?m)BEGIN .*? END. Dit is een vreemde Ruby gril omdat andere engines (?m) gebruiken voor de “^ en $ match op elke regel” mode.
Zie de sectie over inline modifiers voor sappige details over drie extra functies: midden in de string aanzetten, uitzetten met (?-m), of alleen toepassen op de inhoud van een non-capture groep met (?m:foo)
Ruby laat je ook de m vlag toevoegen aan het eind van je regex string. U kunt bijvoorbeeld gebruiken:block_regex = /BEGIN .*? END/m
(directe link)
Origines van DOTALL
De eenregelige modus wordt ook vaak DOTALL genoemd (wat staat voor “dot matches all”) vanwege de PCRE_DOTALL optie in PCRE, de re.DOTALL optie in Python en de Pattern.DOTALL optie in Java.
Ik heb verschillende keren horen beweren dat “DOTALL een Python ding is”, maar dit leek te komen van mensen die niet gehoord hadden van de equivalente opties in PCRE en Java. Toch deed dit me afvragen: waar is DOTALL voor het eerst verschenen? Kijkend naar het PCRE Change Log en oude Python documentatie, lijkt het erop dat het verscheen in PCRE met versie 0.96 (oktober 1997), in Python met versie 1.5 (februari 1998), en daarna in Java 1.4 (februari 2002). Het gat tussen de PCRE en Python introducties was niet overtuigend – het woord zou in omloop kunnen zijn geweest in eerdere beta versies, of zelfs in andere tools – dus vroeg ik Philip Hazel (de vader van PCRE) er naar. Hij antwoordde:
Ik geloof dat ik het heb uitgevonden – ik had het in ieder geval nog niet elders gezien toen ik probeerde een naam te bedenken voor de PCRE-optie die overeenkomt met Perl’s /s optie. (“S” staat daar voor “single-line” (…) dus ik wilde een betere naam.)
Daar. Degenen die van een beetje geschiedenis houden, zullen misschien genieten van dit smakelijke weetje.
(directe link)
Multilijn (^ en $ komen overeen op elke regel): m (behalve Ruby)
In alle grote engines behalve Ruby komen de ankers ^ en $ standaard alleen overeen (respectievelijk) aan het begin en het einde van de tekenreeks.
In Ruby komen ze overeen aan het begin en het einde van elke regel, en er is geen manier om deze functie uit te schakelen. Dit is eigenlijk een redelijke manier om dingen te doen, waarmee Ruby zichzelf gedeeltelijk aflost voor het gebruik van m voor DOTALL mode wanneer andere engines s gebruiken.
In andere engines, als je wilt dat patronen zoals ^Define en >>>$ overeenkomen (respectievelijk) aan het begin en het einde van elke regel, moeten we die eigenschap aanzetten.
Deze eigenschap wordt meestal multi-line (vandaar de m) genoemd, omdat de ankers ^ en $ op meerdere regels werken.
Voor verschillende engines zijn er twee manieren om het aan te zetten: als een inline modifier (?m) of als een optie in de regex methode of functie.
Ruby
In Ruby komen de ankers ^ en $ altijd overeen op alle regels. Er is geen manier om deze optie uit te zetten. Dit is eigenlijk best een leuke manier om dingen te doen, omdat, zoals in de meeste smaken, er aparte ankers zijn voor het begin en einde van strings:
Aan de andere kant kan men Ruby’s keuze betreuren om de m vlag en modifier op een niet-standaard manier te gebruiken (zie DOTALL).
Inline Modifier (?m)
In .NET, PCRE (C, PHP, R…), Perl, Python, Java en Ruby (maar niet JavaScript), kunt u de inline modifier (?m) gebruiken, bijvoorbeeld in (?m)^cat. Zie de sectie over inline modifiers voor sappige details over drie extra functies (niet beschikbaar in Python): midden in de string aanzetten, uitzetten met (?-m), of alleen toepassen op de inhoud van een niet-capture groep met (?m:foo)
.NET
Afgezien van de (?m) inline modifier, hebben .NET talen de Multiline optie. In C# kunt u bijvoorbeeld gebruiken:
var catRegex = new Regex("^cat", RegexOptions.IgnoreCase | RegexOptions.Multiline);
Perl
Naast de (?m) inline-modifier kunt u in Perl ook de vlag m toevoegen na het scheidingsteken waarmee uw patroon wordt afgesloten. Je kunt bijvoorbeeld gebruiken:if ($the_subject =~ m/^cat/m) { … }
PCRE (C, PHP, R…)
Naast de (?m) inline-modifier kunt u met PCRE de PCRE_MULTILINE-modus instellen wanneer u de functie pcre_compile() (of een vergelijkbare functie) aanroept:
cat_regex = pcre_compile( "^cat", PCRE_CASELESS | PCRE_MULTILINE, &error, &erroroffset, NULL );
In PHP wordt de PCRE_MULTILINE-optie doorgegeven via de vlag m, die u in uw regexstring kunt toevoegen na het afsluitende scheidingsteken. U kunt bijvoorbeeld gebruiken:$cat_regex = '~^cat~m';
Python
Naast de (?m) inline modifier, heeft Python de MULTILINE optie. U kunt bijvoorbeeld het volgende gebruiken:cat_regex = re.compile("^cat", re.IGNORECASE | re.MULTILINE)
Java
Naast de (?m) inline-modifier heeft Java de MULTILINE-optie. Zo kunt u bijvoorbeeld gebruiken:
Pattern catRegex = Pattern.compile( "^cat", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE );
JavaScript
In JavaScript is uw enige optie de vlag m toe te voegen na het afsluitende scheidingsteken van uw patroon. U kunt bijvoorbeeld gebruiken:var catRegex = /^cat/m;
(directe link)
Free-Spacing: x (behalve JavaScript)
Aan elke spatie in een regexreeks wordt standaard een teken toegevoegd dat moet worden gematcht. In talen waarin je regex-tekenreeksen op meerdere regels kunt schrijven, geven de regeleinden ook letterlijke tekens aan waarop moet worden gematcht. Omdat je geen spaties kunt invoegen om groepen met verschillende betekenissen van elkaar te scheiden (zoals je doet tussen zinnen en alinea’s als je in het Engels schrijft), kan een regex moeilijk leesbaar worden, zoals bijvoorbeeld de Meaning of Life regex van de regex humor pagina:^(?=(?!(.))()(?-1)(?<!\d(?<=(?!)\d))).$
Gelukkig genoeg ondersteunen veel engines een free-spacing mode waarmee je je regex kunt belichten. Je kunt bijvoorbeeld spaties toevoegen tussen de tokens. In PHP zou je dit kunnen schrijven – let op de x-vlag na het laatste scheidingsteken ~:$word_with_digit_and_cap_regex = '~ ^ (?=\D*\d) \w*\w* $ ~x';
Maar waarom op één regel blijven? Je kan je regex verspreiden over zoveel lijnen als je wil-indenting en commentaar toevoegen- die worden ingeleid door een #. In C# kun je bijvoorbeeld iets als dit doen:
var wordWithDigitAndCapRegex = new Regex(@"(?x) # Free-spacing mode ^ # Assert that position = beginning of string ######### Lookahead ########## (?= # Start lookahead \D* # Match any non-digits \d # Match one digit ) # End lookahead ######## Matching Section ######## \w* # Match any word chars # Match one upper-case letter \w* # Match any word chars $ # Assert that position = end of string");
Deze modus wordt free-spacing modus genoemd. Je ziet het ook wel whitespace mode, comment mode of verbose mode genoemd worden.
Het kan overkill zijn in een simpele regex zoals hierboven (hoewel iedereen die je code moet onderhouden je er dankbaar voor zal zijn). Maar als je een serieus regex patroon maakt zoals die in de truuk om getallen te matchen in gewoon Engels… Tenzij je een masochist bent, heb je geen keus.
Merk op dat binnen een karakter klasse, het spatie teken en de # (die anders commentaar introduceert) nog steeds worden gehonoreerd – behalve in Java, waar ze beide moeten worden ge-escaped als je deze karakters wilt matchen.
Voor diverse engines zijn er twee manieren om de spatie-vrij modus aan te zetten: als een inline modifier of als een optie in de regex methode of functie.
De spatie-vrij modus is prachtig, maar er zijn een paar kleine gevaren waar je je bewust van moet zijn, omdat je je dan misschien achter de oren krabt waarom een patroon niet werkt zoals je verwacht.
Struikelgevaar #1: De betekenis van spatie
Ten eerste, u kunt niet langer Nummer: \om overeen te komen met een tekenreeks zoals Nummer: 24. De reden is dat de spatie in : \niet langer overeenkomt met een spatie. We zijn in vrije-spatie modus, weet je nog? Dat is de bedoeling.
Om met een spatie overeen te komen, moet je die specificeren. De twee belangrijkste manieren om dit te doen zijn door het in een karakter klasse te plaatsen, of door het te escapen met een backslash. Elk van deze manieren zou werken: Nummer:\d+ of Nummer:\d+
Natuurlijk zou Nummer:\s\d+ ook overeenkomen, maar onthoud dat \s met veel meer overeenkomt dan een spatieteken. Het kan bijvoorbeeld overeenkomen met een tab of een regeleinde. Dit is misschien niet wat u wilt.
Trip Hazard #2: Late Start
Ten tweede kunt u overmoedig worden in de kracht van vrije spaties en iets als dit proberen om de regex op zichzelf te laten staan:
var wordWithDigitAndCapRegex = new Regex(@" (?x) # Free-spacing mode ^ # Beginning of string etc # Match the literal chars e,t,c");
Het probleem hiermee is dat hoewel het lijkt alsof de vrije spatie modifier (?x) het eerste is in je regex, maar dat is niet zo.
Na de openings dubbele aanhalingsteken “, hebben we een regeleinde en een aantal spaties. De engine probeert die te evenaren, omdat we in dat stadium nog niet in de vrij-spatie modus zijn. Die modus wordt pas ingeschakeld als we (?x) tegenkomen. Deze regex zal nooit overeenkomen met de string etc en meer, omdat tegen de tijd dat we het begin van string anker ^ tegenkomen, we geacht worden al een regeleinde en spatie tekens te hebben gematched!
Dit is de reden waarom als je naar het eerste voorbeeld kijkt, je zult zien dat de vrije-spatie modifier (?x) het allereerste is na het openende quote karakter.
Whitespace wordt niet alleen uit het patroon geknipt
Zelfs al wordt whitespace genegeerd, de positie van een whitespace scheidt nog steeds het vorige token van het volgende. Bijvoorbeeld,
✽ (A)\1 2 is niet hetzelfde als (A)\12. De eerste komt overeen met AA2, de tweede met A in .NET, PCRE, Perl en Ruby (12 is de octale code voor het linefeed teken)
✽ \p{Nd} is geldig, maar \p{N d} niet – behalve in Perl en Ruby
JavaScript
JavaScript ondersteunt geen vrije-spatie modus. In JavaScript, om overeen te komen met om het even welk karakter, inclusief regeleinden, gebruik een constructie zoals . Deze tekenklasse komt overeen met één teken dat ofwel een niet-cijferig teken ofwel een cijfer is. Daarom komt het overeen met elk teken.
Een andere JavaScript oplossing is het gebruik van de XRegExp regex library. Als je oneindig veel tijd hebt, kun je ook proberen PCRE over te zetten naar JavaScript met behulp van Emscripten, zoals Firas schijnt te hebben gedaan op regex 101.
Inline Modifier (?s)
In .NET, PCRE (C, PHP, R…), Perl, Python, Java en Ruby (maar niet JavaScript), kun je de inline modifier gebruiken (?x), dit is bijvoorbeeld een verluchte regex om herhaalde woorden te matchen:(?x) (\w+) + \b
Zie ook de sectie over inline modifiers.
.NET
Naast de (?x) inline modifier, hebben .NET talen de IgnorePatternWhitespace optie. In C# kunt u bijvoorbeeld gebruiken:
var repeatedWordRegex = new Regex(@" (\w+) + \b", RegexOptions.IgnorePatternWhitespace );
Perl
Naast de (?x) inline modifier kunt u in Perl de vlag x toevoegen na het scheidingsteken waarmee uw patroon wordt afgesloten. Je kunt bijvoorbeeld gebruiken:if ($the_subject =~ m/(\w+) + \b/x) { … }
PCRE (C, PHP, R…)
Naast de (?x) inline-modifier kunt u met PCRE de modus PCRE_EXTENDED instellen wanneer u de functie pcre_compile() (of een vergelijkbare functie) aanroept:
repeated_word_regex = pcre_compile( "(\w+) + \b", PCRE_EXTENDED, &error, &erroroffset, NULL );
In PHP wordt de optie PCRE_EXTENDED doorgegeven via de vlag x, die u in uw regexstring kunt toevoegen na het scheidingsteken aan het einde van het patroon. U kunt bijvoorbeeld gebruiken:$repeated_word_regex = '~(\w+) + \b~x';
Python
Naast de (?x) inline modifier, heeft Python de VERBOSE optie. U kunt bijvoorbeeld het volgende gebruiken:repeated_word_regex = re.compile(r"(\w+) + \b", re.VERBOSE)
Java
In tegenstelling tot andere engines worden in een Java-tekenklasse hashes, commentaar en spaties genegeerd, dus u moet deze escapen als u deze tekens in een klasse wilt gebruiken, bijvoorbeeld +
Naast de (?x) inline-modifier, heeft Java de COMMENTS-optie. U kunt bijvoorbeeld gebruiken:
Pattern repeatedWordRegex = Pattern.compile( "(\w+) + \1\b", Pattern.COMMENTS );
Ruby
Naast de (?x) inline modifier, kunt u in Ruby de x vlag toevoegen aan het eind van uw regex string. Bijvoorbeeld, u kunt gebruiken:repeated_word_regex = /(\w+) + \b/x
(directe link)
Andere modifiers
Sommige engines ondersteunen modifiers en vlaggen naast i, s, m en x. Ik ben van plan deze te behandelen in de pagina’s die aan deze smaken zijn gewijd.
Bijvoorbeeld,
✽ .NET heeft de (?n) modifier (ook toegankelijk via de ExplicitCapture optie). Deze verandert alle (haakjes) in niet-vastleggende groepen. Om te vangen, moet u named groups gebruiken.
✽ Java heeft de (?d) modifier (ook toegankelijk via de UNIX_LINES optie). Wanneer deze aan staat, is het line feed karakter de enige die de punt . (die niet overeenkomt met regeleinden tenzij DOTALL aan staat) en de ankers ^ en $ (die overeenkomen met regelbegin en -einde in multiline modus.)
✽ Perl heeft verschillende andere vlaggen. Zie de modifier sectie van de documentatie.
✽ PCRE heeft de (?J) modifier (ook beschikbaar in code via de PCRE_DUPNAMES optie). Als deze optie is ingesteld, mogen verschillende vangstgroepen dezelfde naam gebruiken, maar krijgen ze verschillende nummers.
(directe link)
✽ PCRE heeft de (?U) modifier (ook beschikbaar in code via de PCRE_UNGEDY optie). Als deze is ingesteld, zijn quantifiers standaard niet-greedy. Door een ? toe te voegen worden ze greedy.
(directe link)
✽ PCRE heeft de (?X) modifier (ook beschikbaar in code via de PCRE_EXTRA optie). Historisch gezien is deze mode gebruikt om nieuwe mogelijkheden in ontwikkeling mogelijk te maken. Op dit moment geeft het fouten als tokens zoals B worden gebruikt in een tekenklasse (waar het normaal overeenkomt met de hoofdletter B, in tegenstelling tot buiten een tekenklasse, waar het een niet-woord-grens-bewering is).
✽ PCRE heeft een aantal speciale modifiers die aan het begin van het patroon kunnen worden ingesteld (deze worden hieronder getoond). Daarnaast kunnen veel opties naar de pcre_compile() familie van functies gestuurd worden, als je daar toegang toe hebt. Voor details hierover, haal pcre_compile.html uit de doc folder door PCRE te downloaden.
(directe link)
PCRE’s Special Start-of-Pattern Modifiers
PCRE heeft een aantal “special modifiers” die je kunt instellen aan het begin van een patroon. In plaats van de standaard (?z) syntax voor inline modifiers, ziet de speciale modifier syntax er uit als (*MYMODIFIER). Deze modifiers zijn vooral nuttig in contexten waar PCRE is geïntegreerd in een tool of een taal-als ze een aantal opties vervangen die je naar pcre_compile() zou sturen.
UTF Strings
Aannemende dat PCRE is gecompileerd met de relevante opties, kunt u de engine opdracht geven de onderwerpstring als verschillende soorten UTF-strings te behandelen.
✽ (*UTF) is een generieke manier om het onderwerp als een UTF-string te behandelen-die detecteert of het moet worden behandeld als UTF-8, UTF-16 of UTF-32.
✽ (*UTF8), (*UTF16) en (*UTF32) behandelen de tekenreeks als een van de drie specifieke UTF-coderingen.
Unicode-eigenschappen voor \d en \w
De standaardinstelling is dat \d alleen met ASCII-cijfers overeenkomt, terwijl \w alleen met ASCII-cijfers, letters en onderstrepingen overeenkomt.
Met de (*UCP)-modifier (die staat voor Unicode Character Properties) kunnen deze tokens overeenkomen met Unicode-cijfers en -woordkarakters.
Bijv. (*UCP)\d+ :: \w+ komt overeen met 1۳۲١८৮੪ :: Aれま래도ᚠᚱᚩ
(Zie demo).
In combinatie met (*UCP) kan het ook nodig zijn om een van de (*UTF) modifiers te gebruiken. Om te zien hoe dit werkt, kunt u de uitvoer van dit programma met een standaard Xampp PHP bekijken:
$string = '1۳۲١८৮੪ :: Aれま래도ᚠᚱᚩ';$utfregex = "~\d+ :: \w+~";$utfregex = "~(*UCP)\d+ :: \w+~";$utfregex = "~(*UTF)(*UCP)\d+ :: \w+~";$utfregex = "~(*UTF)\d+ :: \w+~";$utfregex = "~\d+ :: \w+~u";foreach (range(0, 4) as $i) { echo "$i: ".preg_match($utfregex,$string)."<br />"; }// Output:// 0: 0// 1: 0// 2: 1 => (*UTF)(*UCP)// 3: 0// 4: 1 => The u flag produces the same result as (*UTF)(*UCP)
Modifiers voor regeleinde
De standaardinstelling is dat u bij het compileren van PCRE aangeeft wat als regeleinde moet worden beschouwd wanneer een . wordt aangetroffen (de punt komt niet overeen met regeleinde, tenzij in dotall-modus), evenals het gedrag van de ankers ^ en $ in multiline-modus. U kunt deze standaard opheffen met de volgende modifiers:
✽ (*CR) Alleen een carriage return wordt beschouwd als een regeleinde
✽ (*LF) Alleen een line feed wordt beschouwd als een regeleinde (zoals op Unix)
✽ (*CRLF) Alleen een carriage return gevolgd door een line feed wordt beschouwd als een regeleinde (zoals op Unix)
✽ (*CRLF) Alleen een carriage return gevolgd door een line feed wordt beschouwd als een regeleinde (zoals op Unix)
✽ wordt beschouwd als een regeleinde (zoals onder Windows)
✽ (*ANYCRLF) Elk van de bovenstaande drie wordt beschouwd als een regeleinde
✽ (*ANY) Elke Unicode newline-sequentie wordt beschouwd als een regeleinde
Bijv, (*CR)\w+.\w+ komt overeen met Lijn1nLijn2 omdat de punt kan overeenkomen met de \n, die niet wordt beschouwd als een regeleinde. Zie demo.
Het regelen van \R
Het \R metacharacter komt standaard overeen met elke Unicode newline-sequence. Als UTF-8 modus uit staat, zijn deze newline reeksen het \n paar, maar ook de carriage return, line feed, vertical tab, form feed of next line karakters. In UTF-8 modus komt de token ook overeen met het scheidingsteken voor de regel en de alinea.
Twee start-of-pattern modifiers stellen u in staat het gedrag van \R te veranderen:
✽ Met (*BSR_ANYCRLF) komt \R alleen overeen met de \r-n tekenreeks, \r of \n. Dit kan ook worden ingesteld als PCRE wordt gecompileerd of aangevraagd via de PCRE_BSR_ANYCRLF optie
✽ Met (*BSR_UNICODE) komt \R overeen met elke Unicode newline-sequentie (en overschrijft de PCRE_BSR_ANYCRLF optie als die is ingesteld). Dit kan ook worden ingesteld wanneer PCRE wordt gecompileerd of aangevraagd via de PCRE_BSR_UNICODE optie
Reguleren van uitlopende patronen
Om het aantal keren dat PCRE de match() functie aanroept te beperken, gebruikt u de (*LIMIT_MATCH=x) modifier, waarbij u x instelt op het gewenste aantal.
Om recursie te beperken, gebruik je (*LIMIT_RECURSION=d), waarbij je d instelt op het diepst toegestane recursieniveau.
Optimalisaties uitschakelen
(directe link)
In de standaardinstelling bestudeert PCRE het patroon en maakt automatisch een gekwantificeerd token atomisch als het volgende token incompatibel is-bijvoorbeeld door A+X te veranderen in A++X. De (*NO_AUTO_POSSESS) modifier schakelt deze optimalisatie uit. Gebruik dit wanneer je pcretest wilt gebruiken om twee patronen te benchmarken en jezelf een goed gevoel wilt geven over alle cycli die auto-possessification je bespaart.
De standaardinstelling is dat PCRE verschillende optimalisaties uitvoert om er sneller achter te komen of een match zal falen. De (*NO_START_OPT) modifier schakelt deze optimalisaties uit.
Lege matches uitschakelen
In PCRE2, (*NOTEMPTY) vertelt de engine om geen lege matches te retourneren. Evenzo geeft (*NOTEMPTY_ATSTART) aan dat er geen lege overeenkomsten aan het begin van het onderwerp mogen worden teruggegeven.
Automatische verankeringsoptimalisatie uitschakelen
In PCRE2 geeft PCRE2_NO_DOTSTAR_ANCHOR aan dat er geen automatische verankering mag plaatsvinden van patronen die beginnen met .*
en de beste Regex-truc ooit niet!!!
De 1001 manieren om Regex te gebruiken