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ó.