A reguláris kifejezés egy kis nyelv szövegminták leírására. Megtalálhat számlaszámot, felismerhet dátumformát, mezőt emelhet ki naplóból vagy egységesítheti a whitespace-t. Azért tűnik titokzatosnak, mert kevés írásjel sok jelentést hordoz. Érthetővé akkor válik, ha nem egyetlen varázsszövegként nézzük, hanem balról jobbra haladó döntések soraként: minden token megmondja, milyen karakter vagy pozíció következhet.
A literál önmagát keresi
A legtöbb betű és szám pontosan saját magára illeszkedik. A konto minta ezt az öt karaktert keresi. A pont, csillag, zárójel és más metakarakter külön jelentést kap.
Ha írásjelet szó szerint akarunk, escape szükséges. A \. pontot keres, a sima pont rendszerint szinte bármely karaktert.
A karakterosztály egyetlen pozíciót ír le
Az [abc] egy a, b vagy c karaktert fogad el, nem az egész „abc” szót. A [0-9] számjegytartomány, a negált class pedig a felsoroláson kívüli jeleket jelenti.
A \d és \s Unicode-viselkedése engine és flag függő. Teljes szavak alternatívája csoportba való, például (kutya|macska).
A quantifier az ismétlést szabályozza
A csillag nulla vagy több, a plusz legalább egy, a kérdőjel opcionális előfordulást enged. A kapcsos forma pontos vagy korlátozott darabszámot ad. Mindig a közvetlenül előtte álló tokenre vagy csoportra vonatkozik.
A greedy változat először a lehető legtöbbet fogyasztja el, majd szükség esetén visszaad karaktereket. A lazy változat a minimumról indul. A megfelelő választást az adat valódi határa dönti el.
Az anchor pozíciót ellenőriz
A kezdet, vég, szóhatár és lookaround nem fogyaszt karaktert. Egy teljes érték validálásához rendszerint kezdő- és véganchor kell, míg kereséshez ezek túl szűkek lehetnek.
A multiline flag megváltoztathatja a sor elejének és végének jelentését. A pattern flags nélkül nem teljes szerződés.
A csoport szervez, rögzít és választ
A zárójelek tokeneket kapcsolnak össze, hogy quantifier vagy alternatíva vonatkozzon rájuk. A capturing group megőrzi a talált szöveget. A névvel ellátott year stabilabb, mint a törékeny sorszám.
Non-capturing group akkor jó, ha csak szerkezet kell. A felesleges captures megnehezíti a módosítást.
A flags megváltoztatja a környezetet
Case-insensitive, multiline, dot-all, global és Unicode mód eltérő eredményt adhat. Ugyanaz a source más engine-ben mást jelenthet.
JavaScript, PCRE, Python, Java és .NET nem ugyanazt a lookbehind, Unicode property és replacement szintaxist támogatja. A mintát a tényleges runtime-ban kell tesztelni.
A lookaround a környezetet vizsgálja
A lookahead és lookbehind megkövetelhet környező szöveget anélkül, hogy az a match része lenne. Hasznos, de csökkentheti az olvashatóságot és hordozhatóságot.
Ha sok negatív assertion üzleti szabályt szimulál, egyszerűbb lehet előbb struktúrát kinyerni, majd normál kóddal ellenőrizni.
A replacement külön kis nyelv
A helyettesítő string group reference-t, dollárjelet és backslasht értelmezhet. Helyes search pattern mellett is sérülhet a kimenet.
Felhasználói replacementhez literal API vagy callback biztonságosabb. A teszt a teljes átalakított szöveget hasonlítsa.
A Unicode-ban egy látható karakter több egység lehet
Egy ékezetes betű vagy emoji több code pointból állhat. A pont és quantifier nem mindig azt számolja egy karakternek, amit a felhasználó. Grapheme cluster kezeléshez speciális engine-támogatás vagy Unicode könyvtár kellhet.
Az [A-Za-z] nevekhez túl szűk. Unicode letter property jobb lehet, de a doménnek továbbra is el kell döntenie, milyen jelek engedélyezettek.
A keresési művelet jelentése különbözik
Az első match, minden match és a teljes input validálása más API-szerződés. A kód nevezze meg a szándékot, és kezelje a nulla vagy több találatot.
Ha a dokumentumnak pontosan egy azonosítót kell tartalmaznia, a második találat hiba, nem ok arra, hogy csendben az elsőt válasszuk.
A regex és parser együtt is dolgozhat
Regex kiválaszthat jelölt sorokat, majd strukturált parser ellenőrizheti a dátumot, számot és enumot. Így a minta lokális és a hibák doménnyelven adhatók vissza.
HTML, JSON vagy programnyelv teljes feldolgozásához jobb a valódi parser. Az escaping és egymásba ágyazás gyorsan kinövi a regex szerepét.
A jó minta magyarázható
Pozitív és negatív példák, inputlimit és flags tartozik hozzá. Tokenenként hétköznapi mondattá fordítható.
A regex ekkor nem írásjelrejtvény, hanem pontos eszköz egy jól körülhatárolt szöveges struktúrához.
A nulla hosszúságú match külön figyelmet igényel
Egy pattern úgy is sikeres lehet, hogy egyetlen karaktert sem fogyaszt. Global keresési ciklusban ez ugyanazon a pozíción ismétlődhet, ha a könyvtár nem léptet automatikusan. A végeredmény végtelen loop vagy meglepően sok üres találat lehet.
A fogyasztó kódnak ismernie kell az API viselkedését, és tesztelnie kell az üres inputot, valamint a karakterek közötti pozíciókat. Ha a domén valódi adatot vár, érdemes olyan pattern-t írni, amely legalább egy karaktert kötelezően elfogyaszt.
A normalizálás nem része automatikusan az illesztésnek
Vizuálisan azonos Unicode szöveg lehet előre összetett vagy combining karakterekből álló forma. A regex byte- vagy code-point szinten eltérő eredményt adhat. Ha a domén egyenértékűnek tekinti őket, a bemenetet meghatározott normalization formára kell hozni.
A normalizálás azonban megváltoztathat identifier- vagy biztonsági jelentést. Nem szabad általános tisztításként minden mezőre alkalmazni. A szerződés mondja meg, melyik mezőn, melyik formában történik.
A capture és a teljes match nem ugyanaz
Egy pattern szélesebb környezetet illeszthet, miközben csak egy named groupot használ üzleti értékként. A kódnak világosan jeleznie kell, melyik rész az eredmény, és a környezetet miért kellett bevonni.
Replacementnél a capture hiánya üres stringet vagy hibát okozhat engine szerint. Az opcionális csoport minden állapotát külön tesztelni kell, nem csak azt, amikor megtalálható.