Reguláris kifejezés (Regular Expression): definíciója és használata

A reguláris kifejezés egy speciális mintázat, amely segít szövegek keresésében és feldolgozásában. Használatával egyszerűbbé válik adatok ellenőrzése, szűrése vagy átalakítása programozásban és mindennapi feladatokban. Fedezd fel, hogyan működik!
ITSZÓTÁR.hu
35 Min Read
Gyors betekintő

A digitális korban az adatok a legértékesebb erőforrások közé tartoznak. Naponta hatalmas mennyiségű szöveges információ keletkezik, amelyet rendszerezni, elemezni, keresni és módosítani kell. E feladatok hatékony elvégzéséhez elengedhetetlenek a hatékony mintakeresési és szövegkezelési eszközök. A reguláris kifejezések, angolul Regular Expressions, vagy röviden Regex (vagy Regexp), pontosan ilyen eszközök: rendkívül rugalmas és erőteljes mechanizmusok szöveges minták leírására és illesztésére.

Egy reguláris kifejezés lényegében egy speciális karaktersorozat, amely egy keresési mintát definiál. Ez a minta aztán felhasználható arra, hogy egy nagyobb szövegben megtaláljuk az adott mintának megfelelő részeket, ellenőrizzük egy szöveg formátumát, vagy akár lecseréljük a mintának megfelelő részeket valami másra. Képzeljük el, hogy egy hatalmas dokumentumban szeretnénk megtalálni az összes telefonszámot, e-mail címet, vagy egy adott formátumú dátumot. Manuálisan ez szinte lehetetlen lenne, de egy reguláris kifejezéssel pillanatok alatt elvégezhető. A reguláris kifejezések ereje abban rejlik, hogy nem csupán pontos karakterláncokat tudnak keresni, hanem komplex mintákat, amelyek változó elemeket is tartalmazhatnak, például számokat, betűket, szóközöket, vagy bizonyos számú ismétlődést.

A reguláris kifejezések használata széles körben elterjedt a számítástechnikában. Programozók, rendszergazdák, adattudósok és szövegszerkesztők egyaránt alkalmazzák őket mindennapi munkájuk során. Megtalálhatók szinte minden modern programozási nyelvben (Python, JavaScript, PHP, Java, C#, Ruby, Perl, stb.), szövegszerkesztőkben (VS Code, Sublime Text, Notepad++), parancssori eszközökben (grep, sed, awk) és adatbázis-rendszerekben (SQL).

A Reguláris Kifejezések Története és Elméleti Alapjai

A reguláris kifejezések gyökerei a formális nyelvek elméletébe nyúlnak vissza, amely a számítástudomány egyik alapvető ága. Az elméletet Stephen Cole Kleene matematikus vezette be az 1950-es években, a neuronhálózatok matematikai modelljeinek leírására. Ő definiálta a „reguláris eseményeket” (regular events), amelyek egy adott nyelven belüli mintákat írnak le. Ez az elméleti alap szolgált a későbbi gyakorlati implementációk kiindulópontjául.

Az 1960-as években Ken Thompson, a Unix operációs rendszer egyik megalkotója, beépítette Kleene reguláris kifejezés elméletét a QED szövegszerkesztőbe, majd később a híres grep parancsba (amely a „globally search for a regular expression and print” rövidítése). Ez volt az első széles körben elterjedt gyakorlati alkalmazása a reguláris kifejezéseknek, és jelentősen hozzájárult a népszerűségükhöz a Unix környezetben.

Az 1970-es és 1980-as években további Unix eszközök, mint a sed (stream editor) és az awk, is átvették és továbbfejlesztették a reguláris kifejezések használatát. Ezek az eszközök lehetővé tették a komplex szövegmanipulációt és adatelemzést a parancssorból, ami forradalmasította a rendszergazdák és fejlesztők munkáját.

A modern reguláris kifejezések fejlődésének következő jelentős állomása az 1990-es években érkezett el, a Perl programozási nyelvvel. Larry Wall, a Perl megalkotója, rendkívül gazdag és erőteljes reguláris kifejezés motorral látta el a nyelvet, ami számos új funkciót vezetett be, mint például a visszahivatkozások, nem-mohó illesztések és előretekintő állítások. A Perl reguláris kifejezés szintaxisa annyira befolyásos lett, hogy a legtöbb modern programozási nyelv és eszköz ezt vette alapul, és ma már a PCRE (Perl Compatible Regular Expressions) a de facto szabvány a komplex reguláris kifejezések számára.

Ma már a reguláris kifejezések a programozás alapvető eszköztárának részét képezik. Bár a szintaxisuk elsőre bonyolultnak tűnhet, elsajátításuk hatalmasan növeli a szövegkezelési feladatok hatékonyságát és automatizálási képességét.

Alapvető Szintaktika és Metakarakterek

A reguláris kifejezések ereje a metakarakterekben rejlik. Ezek olyan speciális karakterek, amelyek nem önmagukban, hanem egy adott jelentéssel bírnak a mintában. A reguláris kifejezések alapja a literális karakterek és a metakarakterek kombinációja.

Literális Karakterek

A legtöbb karakter önmagában is literális jelentéssel bír, azaz önmagát illeszti. Például a „macska” kifejezés pontosan a „macska” szót fogja megtalálni egy szövegben. Ha egy metakaraktert szeretnénk literálisként illeszteni, akkor elé kell tenni egy visszaper jelet (\), ami „escape-eli” azt. Például, ha egy pontot (.) szeretnénk illeszteni, ami egyébként egy metakarakter, akkor a mintánk „\.” lesz.

A Pont (.) – Bármely Karakter

A pont metakarakter (.) illeszkedik bármely egyetlen karakterre, kivéve az új sor karaktert. Ez rendkívül hasznos, ha egy mintában egy ismeretlen vagy változó karakter van.

  • Példa: k.t illeszkedik a „kut”, „kat”, „köt”, „k9t” szavakra.
  • Példa: alma. illeszkedik az „almaf”, „almak”, „alma?” szavakra.

Karakterosztályok ([]) – Egy Karakter a Sok Közül

A szögletes zárójelek ([]) egy karakterosztályt definiálnak. Ez azt jelenti, hogy a zárójelek között felsorolt karakterek közül bármelyik egyetlen karakterre illeszkedik. A karakterosztályon belül a metakarakterek elveszítik speciális jelentésüket, kivéve néhányat (pl. -, ^).

  • Példa: [aeiou] illeszkedik bármely magánhangzóra.
  • Példa: [0123456789] illeszkedik bármely számjegyre.

Tartományok (-) Karakterosztályon Belül

A kötőjel (-) használható tartományok megadására karakterosztályon belül, ami rendkívül kényelmes a hosszú listák helyett.

  • Példa: [a-z] illeszkedik bármely kisbetűre.
  • Példa: [A-Z] illeszkedik bármely nagybetűre.
  • Példa: [0-9] illeszkedik bármely számjegyre.
  • Példa: [a-zA-Z0-9] illeszkedik bármely alfanumerikus karakterre.

Tagadás (^) Karakterosztályon Belül

Ha a ^ karaktert a karakterosztály nyitó szögletes zárójele után közvetlenül helyezzük el ([^...]), az azt jelenti, hogy a minta illeszkedik bármely karakterre, kivéve a felsoroltakat.

  • Példa: [^0-9] illeszkedik bármely nem-számjegy karakterre.
  • Példa: [^aeiou] illeszkedik bármely nem-magánhangzó karakterre.

Előre Definiált Karakterosztályok (Shorthand Character Classes)

A gyakran használt karakterosztályokhoz léteznek rövidítések, amelyek megkönnyítik az írást és az olvasást.

  • \d: Illeszkedik bármely számjegyre (digit). Egyenértékű a [0-9]-cel.
    • Példa: \d\d\d illeszkedik „123”-ra, „456”-ra.
  • \D: Illeszkedik bármely nem-számjegy karakterre. Egyenértékű a [^0-9]-cel.
    • Példa: \D\D\D illeszkedik „abc”-re, „xyz”-re, de nem „123”-ra.
  • \w: Illeszkedik bármely „szó” karakterre (word character). Ez magában foglalja az angol ábécé betűit (kis- és nagybetűk), számjegyeket és az aláhúzás jelet (_). Egyenértékű a [a-zA-Z0-9_]-vel.
    • Példa: \w+ illeszkedik „szavak_123”-ra.
  • \W: Illeszkedik bármely nem-szó karakterre. Egyenértékű a [^a-zA-Z0-9_]-vel.
    • Példa: \W illeszkedik a szóközre, írásjelekre.
  • \s: Illeszkedik bármely „whitespace” karakterre (space). Ez magában foglalja a szóközt, tabulátort, új sort, kocsi vissza karaktert, űrlaplapozást és függőleges tabulátort.
    • Példa: szó\s\s\szó illeszkedik „szó szó”-ra (három szóközzel).
  • \S: Illeszkedik bármely nem-whitespace karakterre.
    • Példa: \S+ illeszkedik egy összefüggő, szóközöket nem tartalmazó szövegrészre.

Mennyiségi Jelölők (Quantifiers)

A mennyiségi jelölők (kvantifikátorok) azt szabályozzák, hogy egy karakter, karakterosztály vagy csoport hányszor ismétlődhet meg a mintában. Ezek a metakarakterek teszik igazán rugalmassá a reguláris kifejezéseket.

A Csillag (*) – Nulla vagy Több Ismétlődés

A csillag (*) az előtte lévő elem nulla vagy több ismétlődésére illeszkedik.

  • Példa: ab*c illeszkedik „ac”, „abc”, „abbc”, „abbbc” stb. szavakra.
  • Példa: [0-9]* illeszkedik egy üres stringre, egyetlen számjegyre, vagy több számjegy sorozatára.

A Plusz (+) – Egy vagy Több Ismétlődés

A plusz (+) az előtte lévő elem egy vagy több ismétlődésére illeszkedik.

  • Példa: ab+c illeszkedik „abc”, „abbc”, „abbbc” stb. szavakra, de nem illeszkedik „ac”-re.
  • Példa: \d+ illeszkedik „1”, „12”, „12345” stb. számokra, de nem üres stringre.

A Kérdőjel (?) – Nulla vagy Egy Ismétlődés (Opcionális)

A kérdőjel (?) az előtte lévő elem nulla vagy egy ismétlődésére illeszkedik, azaz opcionálissá teszi azt.

  • Példa: colou?r illeszkedik „color” és „colour” szavakra.
  • Példa: https?:\/\/ illeszkedik „http://” és „https://” protokollokra.

Kapcsos Zárójelek ({}) – Pontos Ismétlésszámok

A kapcsos zárójelek ({}) lehetővé teszik az ismétlések számának pontosabb megadását.

  • {n}: Pontosan n számú ismétlődésre illeszkedik.
    • Példa: \d{3} illeszkedik pontosan három számjegyre, pl. „123”.
  • {n,}: Legalább n számú ismétlődésre illeszkedik.
    • Példa: \d{3,} illeszkedik három vagy több számjegyre, pl. „123”, „12345”.
  • {n,m}: Legalább n, de legfeljebb m számú ismétlődésre illeszkedik.
    • Példa: \d{3,5} illeszkedik három, négy vagy öt számjegyre, pl. „123”, „1234”, „12345”.

Mohó (Greedy) vs. Nem-Mohó (Lazy) Illesztések

Alapértelmezés szerint a mennyiségi jelölők mohók (greedy). Ez azt jelenti, hogy a lehető leghosszabb illesztést próbálják megtalálni, miközben még mindig illeszkednek a teljes mintához. Ez gyakran okoz meglepetéseket, ha nem vagyunk tisztában vele.

  • Példa: A minta <.*> egy szövegben, mint <b>Ez egy <em>kiemelt</em> szöveg.</b>.
    • Mohó illesztés: <b>Ez egy <em>kiemelt</em> szöveg.</b> (az első <-től az utolsó >-ig illeszkedik).

Ha a lehető legrövidebb illesztést szeretnénk, akkor a mennyiségi jelölő után egy kérdőjelet (?) kell tenni, ami nem-mohó (lazy) illesztéssé alakítja azt.

  • Példa: A minta <.*?> egy szövegben, mint <b>Ez egy <em>kiemelt</em> szöveg.</b>.
    • Nem-mohó illesztés: <b>, <em>, </em>, </b> (külön illeszkednek).

Ez a viselkedés kritikus fontosságú HTML/XML tag-ek vagy más tag-alapú struktúrák illesztésekor.

Pozícióhoz Kötött Illesztések (Anchors)

A pozícióhoz kötött illesztések megjelölik a szöveghatárokat.
A pozícióhoz kötött illesztések például a szóhatárokat jelölik, így pontosabb keresést tesznek lehetővé.

A pozícióhoz kötött illesztések (horgonyok) nem karakterekre illeszkednek, hanem a szövegben elfoglalt pozíciókra. Ezek segítenek abban, hogy a mintánk csak a szöveg bizonyos részein illeszkedjen.

Kezdőjel (^) – Sor Eleje

A ^ karakter a sor elejére illeszkedik. Ha a minta elején áll, azt jelenti, hogy az illesztésnek a sor elejétől kell kezdődnie.

  • Példa: ^Kezdet illeszkedik a „Kezdet” szóra, ha az egy sor elején van.
  • Példa: ^\d{3} illeszkedik egy olyan sorra, ami három számjeggyel kezdődik.

Fontos megjegyezni, hogy multiline (többsoros) módban (ami egy flag, lásd később) a ^ minden sor elejére illeszkedik, nem csak a teljes szöveg elejére.

Dollárjel ($) – Sor Vége

A $ karakter a sor végére illeszkedik. Ha a minta végén áll, azt jelenti, hogy az illesztésnek a sor végén kell befejeződnie.

  • Példa: Vége$ illeszkedik a „Vége” szóra, ha az egy sor végén van.
  • Példa: \d{3}$ illeszkedik egy olyan sorra, ami három számjeggyel végződik.

Hasonlóan a ^-hez, multiline módban a $ minden sor végére illeszkedik.

Szóhatár (\b)

A \b illeszkedik egy szóhatárra. Egy szóhatár a következő helyeken található:

  • A szó karakter (\w) és egy nem-szó karakter (\W) között.
  • A szó karakter és a szöveg eleje vagy vége között.

Ez rendkívül hasznos, ha egy teljes szót szeretnénk illeszteni, nem pedig egy szó részét.

  • Példa: \bmacska\b illeszkedik a „macska” szóra a „A macska ugat” mondatban, de nem illeszkedik a „macskakő” szó „macska” részére.
  • Példa: \b\d{4}\b illeszkedik egy négyjegyű számra, ami önmagában áll, például egy évszámra.

Nem Szóhatár (\B)

A \B a \b ellentéte; illeszkedik egy nem-szóhatárra. Ez azt jelenti, hogy az illesztésnek egy szón belül kell lennie.

  • Példa: \Bmacska\B nem illeszkedik a „macska” szóra, de illeszkedhetne, ha az egy hosszabb, összetett szó része lenne, pl. „nagymacska”. (Ebben az esetben a „macska” a „nagy” után, és a szó végén van, szóhatárral, így nem illeszkedik. Ez a példa inkább a „bet” mintára a „beton” szóban lenne releváns, pl. \Bbet\B illeszkedik a „beton” szóban a „bet” részre.)
  • Példa: \bbet\B illeszkedik a „beton” szóban a „bet” részre, mert a „bet” elején van szóhatár, de a végén nincs (az „o” követi).

Csoportosítás és Hivatkozás (Grouping and Backreferences)

A zárójelek (()) alapvető fontosságúak a reguláris kifejezésekben, mivel lehetővé teszik a csoportosítást és a rögzítést (capturing).

Csoportosítás ()

A zárójelekkel több karaktert vagy mintát egyetlen egységként kezelhetünk, és kvantifikátorokat alkalmazhatunk rájuk.

  • Példa: (ab)+ illeszkedik az „ab”, „abab”, „ababab” stb. sorozatokra. A + kvantifikátor az „ab” csoportra vonatkozik.
  • Példa: (ha){2} illeszkedik a „haha” szóra.

Alternatíva (|) – Vagy

A függőleges vonal (|) az „vagy” logikai operátor. Lehetővé teszi, hogy több alternatív mintát adjunk meg. A zárójelekkel kombinálva használható, ha az alternatívák egy csoporton belül vannak.

  • Példa: kutya|macska illeszkedik a „kutya” vagy a „macska” szóra.
  • Példa: (piros|kék) autó illeszkedik „piros autó” vagy „kék autó” kifejezésekre.

Rögzítő Csoportok (Capturing Groups) és Visszahivatkozások (\1, \2, …)

Amikor egy mintát zárójelek közé teszünk, az nemcsak csoportosítja azt, hanem a megtalált illesztést rögzíti is. Ezekre a rögzített csoportokra később hivatkozhatunk a mintában (visszahivatkozás) vagy a csereszövegben.

A csoportok számozása balról jobbra történik, a nyitó zárójelek sorrendjében.

  • Példa: (\w+)\s(\w+) illeszkedik két szóra, amelyeket egy szóköz választ el.
    • Az első szó (\w+) az 1. rögzített csoport (\1).
    • A második szó (\w+) a 2. rögzített csoport (\2).
  • Visszahivatkozás a mintában: (\w+)\s\1 illeszkedik olyan szavakra, ahol egy szó kétszer ismétlődik szóközzel elválasztva, pl. „kutya kutya”.
    • (\w+) rögzíti az első szót.
    • \1 hivatkozik az első rögzített csoportra, és elvárja, hogy ugyanaz a szó ismétlődjön.
  • Visszahivatkozás cserénél: Ha a (\w+)\s(\w+) mintát lecseréljük \2 \1-re, az „Elso Masodik” szöveget „Masodik Elso”-re cseréli (szavak felcserélése).

Nem-rögzítő Csoportok (Non-Capturing Groups) (?:…)

Néha csak csoportosítani szeretnénk, de nem akarjuk rögzíteni az illesztést, hogy ne foglaljon memóriát vagy ne befolyásolja a visszahivatkozások számozását. Erre szolgál a (?:...) szintaxis.

  • Példa: (?:kutya|macska) ugat illeszkedik „kutya ugat” vagy „macska ugat” kifejezésekre. A „kutya” vagy „macska” rész nem lesz rögzített csoport.

Előretekintő Állítások (Lookaheads) és Hátratekintő Állítások (Lookbehinds)

Ezek az állítások (assertions) nem illesztenek karaktereket, hanem azt ellenőrzik, hogy egy adott minta követi-e vagy megelőzi-e az aktuális pozíciót, anélkül, hogy az ellenőrzött mintát az illesztés részévé tennék. Rendkívül hasznosak komplex kontextusfüggő illesztésekhez.

Pozitív Előretekintő (Positive Lookahead) (?=…)

A (?=...) illeszkedik, ha a minta, amit a = után adunk meg, követi az aktuális pozíciót.

  • Példa: alma(?=fa) illeszkedik az „alma” szóra, de csak akkor, ha azt a „fa” szó követi. A „fa” szó nem lesz része az illesztésnek.
    • „almafa” esetén illeszkedik az „alma”, „almakörte” esetén nem.
  • Példa: \w+(?=\.com) illeszkedik egy domain névre, ami „.com”-ra végződik, de a „.com” részt nem rögzíti.

Negatív Előretekintő (Negative Lookahead) (?!…)

A (?!...) illeszkedik, ha a minta, amit a ! után adunk meg, nem követi az aktuális pozíciót.

  • Példa: macska(?!kutya) illeszkedik a „macska” szóra, de csak akkor, ha azt nem a „kutya” szó követi.
    • „macskaegér” esetén illeszkedik az „macska”, „macskakutya” esetén nem.

Pozitív Hátratekintő (Positive Lookbehind) (?<=...)

A (?<=...) illeszkedik, ha a minta, amit a <= után adunk meg, megelőzi az aktuális pozíciót. Fontos: a legtöbb regex motorban a hátratekintő minta fix hosszúságú kell, hogy legyen (pl. nem tartalmazhat kvantifikátorokat, mint * vagy +).

  • Példa: (?<=$)\d+ illeszkedik egy számra, de csak akkor, ha azt egy dollárjel ($) előzi meg. A dollárjel nem lesz része az illesztésnek.
    • "$123" esetén illeszkedik a "123", "123 Ft" esetén nem.

Negatív Hátratekintő (Negative Lookbehind) (?

A (? illeszkedik, ha a minta, amit a után adunk meg, nem előzi meg az aktuális pozíciót. Szintén fix hosszúságú mintát igényel.

  • Példa: (?<!https?:\/\/)www\. illeszkedik a "www." kifejezésre, de csak akkor, ha azt nem előzi meg egy "http://" vagy "https://". Ez segíthet elkerülni, hogy URL-eken belüli "www." illeszkedjen, ha csak az önálló "www." érdekel.

Módosító Jelzők (Flags/Modifiers)

A reguláris kifejezések viselkedését módosító jelzőkkel (flags) szabályozhatjuk. Ezeket általában a regex motor inicializálásakor vagy a mintához fűzve adjuk meg.

i (Case-Insensitive / Kis- és Nagybetű Érzéketlen)

A i jelző bekapcsolja a kis- és nagybetűk közötti érzéketlenséget. Ez azt jelenti, hogy a [a-zA-Z]-nek megfelelő illesztések mindkét esetben megtörténnek.

  • Példa: A macska/i minta illeszkedik "macska", "Macska", "MACSKA" stb. szavakra.

g (Global / Globális)

A g jelző (különösen JavaScriptben és más nyelvekben) azt jelenti, hogy az összes illeszkedést meg kell találni a szövegben, nem csak az elsőt. Keresés és csere műveleteknél alapvető.

  • Példa: Ha a/g-vel keresünk a "banana" szóban, az mindhárom 'a' karaktert megtalálja. A a jelző nélkül csak az elsőt.

m (Multiline / Többsoros)

A m jelző megváltoztatja a ^ és $ horgonyok viselkedését. Alapértelmezés szerint ezek a teljes szöveg elejére és végére illeszkednek. A m jelzővel azonban a ^ minden sor elejére, a $ pedig minden sor végére illeszkedik (az új sor karakterek által definiált sorokra).

  • Példa: Szöveg: "Első sor\nMásodik sor".
    • ^\w+ (m nélkül) csak az "Első" szóra illeszkedik.
    • ^\w+/m illeszkedik az "Első" és a "Második" szavakra is.

s (Dotall / Egypontos)

A s jelző megváltoztatja a . metakarakter viselkedését. Alapértelmezés szerint a . nem illeszkedik az új sor karakterre. A s jelzővel azonban a . illeszkedik az új sor karakterre is.

  • Példa: Szöveg: "Sor1\nSor2".
    • Sor1.Sor2 (s nélkül) nem illeszkedik, mert a . nem illeszkedik a \n-re.
    • Sor1.Sor2/s illeszkedik, mert a . illeszkedik a \n-re.

x (Verbose / Bőbeszédű)

A x jelző lehetővé teszi, hogy a reguláris kifejezéseket jobban olvasható formában írjuk meg. Figyelmen kívül hagyja a szóközt és az új sor karaktereket (kivéve, ha escape-elve vannak), és lehetővé teszi a kommentek hozzáadását (# karakterrel kezdődően a sor végéig).

  • Példa:

                /
                ^           # Sor eleje
                (\d{3})     # Három számjegy, rögzítve
                -?          # Opcionális kötőjel
                (\d{3})     # Három számjegy, rögzítve
                -?          # Opcionális kötőjel
                (\d{4})     # Négy számjegy, rögzítve
                $           # Sor vége
                /x
                


    Ez a minta egy telefonszámot illeszthet, mint pl. "123-456-7890" vagy "1234567890", sokkal olvashatóbb formában.

u (Unicode)

A u jelző (különösen JavaScriptben és más nyelvekben) azt biztosítja, hogy a reguláris kifejezés Unicode karakterekkel is helyesen működjön, beleértve a speciális Unicode kategóriákat és tulajdonságokat.

Gyakori Használati Esetek és Példák

A reguláris kifejezések rendkívül sokoldalúak, és számos mindennapi feladatban használhatók. Íme néhány gyakori példa:

E-mail Cím Validálás

Az e-mail címek validálása az egyik leggyakoribb feladat. Fontos megjegyezni, hogy egy "tökéletes" e-mail regex rendkívül bonyolult lenne az RFC szabványok miatt, de egy gyakorlatban jól használható, egyszerűbb verzió is létezik.


^\S+@\S+\.\S+$

  • ^: Sor eleje.
  • \S+: Egy vagy több nem-whitespace karakter (felhasználónév).
  • @: A kukac jel.
  • \S+: Egy vagy több nem-whitespace karakter (domain név).
  • \.: Egy literális pont (escape-elve, mert metakarakter).
  • \S+: Egy vagy több nem-whitespace karakter (top-level domain).
  • $: Sor vége.

Ez a minta illeszkedik például a "user@example.com" címre. Egy összetettebb, de még mindig nem teljesen RFC-kompatibilis minta:


^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

  • [a-zA-Z0-9._%+-]+: Felhasználónév (betűk, számok, pont, aláhúzás, százalék, plusz, kötőjel).
  • @: Kukac.
  • [a-zA-Z0-9.-]+: Domain név (betűk, számok, pont, kötőjel).
  • \.: Pont.
  • [a-zA-Z]{2,}: Top-level domain (legalább két betű).

Telefonszám Validálás

A telefonszámok formátuma országonként és régiónként eltérő, de egy általános minta illeszthet néhány elterjedt formátumot.


^\+?\d{1,3}[-.\s]?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$

  • ^: Sor eleje.
  • \+?: Opcionális plusz jel (nemzetközi hívószámokhoz).
  • \d{1,3}: Országkód (1-3 számjegy).
  • [-.\s]?: Opcionális elválasztó (kötőjel, pont vagy szóköz).
  • \(?\d{3}\)?: Opcionális zárójelezett körzetszám (3 számjegy).
  • [-.\s]?: Opcionális elválasztó.
  • \d{3}: 3 számjegy.
  • [-.\s]?: Opcionális elválasztó.
  • \d{4}: Utolsó 4 számjegy.
  • $: Sor vége.

Ez a minta illeszkedik például "+36-20-123-4567", "(123) 456-7890", "123.456.7890" formátumokra.

Dátum Formátum Ellenőrzés (YYYY-MM-DD)


^\d{4}-\d{2}-\d{2}$

  • ^\d{4}: Négy számjegy az évnek.
  • -: Kötőjel.
  • \d{2}: Két számjegy a hónapnak.
  • -: Kötőjel.
  • \d{2}$: Két számjegy a napnak.

Ez a minta illeszkedik "2023-10-26" formátumra. Nem ellenőrzi a dátumok érvényességét (pl. 30 napos hónapok, szökőévek).

URL Illesztés

URL-ek illesztése rendkívül bonyolult lehet, de egy alapvető minta:


^(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/[a-zA-Z0-9]+\.[^\s]{2,}|[a-zA-Z0-9]+\.[^\s]{2,})$

Ez egy komplex minta, amely többféle URL formátumot próbál lefedni. Részletezés:

  • ^: Sor eleje.
  • https?:\/\/: Opcionális HTTPS vagy HTTP protokoll.
  • (?:www\.|(?!www)): Nem-rögzítő csoport, ami vagy "www." illeszt, vagy biztosítja, hogy ne legyen "www" (ha nincs protokoll).
  • [a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]: Domain név (betűk, számok, kötőjelek).
  • \.: Pont.
  • [^\s]{2,}: Top-level domain (legalább 2 nem-szóköz karakter).
  • |: Vagy (több alternatív URL formátum).
  • $: Sor vége.

Figyelmeztetés: HTML/XML tag-ek reguláris kifejezésekkel történő illesztése és feldolgozása általában nem javasolt. Az XML/HTML nem reguláris nyelvek, ezért a reguláris kifejezések nem képesek megbízhatóan és teljes körűen kezelni az összes lehetséges esetet (pl. beágyazott tagek, kommentek, attribútumok). Erre a feladatra HTML/XML parsereket kell használni.

Szöveg Cseréje (Find and Replace)

A reguláris kifejezések nemcsak keresésre, hanem szöveg cseréjére is használhatók. Ezt a visszahivatkozások teszik különösen erőteljessé.

  • Példa: Szavak felcserélése egy mondatban:
    • Szöveg: "Kovacs Janos"
    • Keresési minta: (\w+)\s(\w+)
    • Csereszöveg: $2 $1 (vagy \2 \1 a nyelvtől függően)
    • Eredmény: "Janos Kovacs"
  • Példa: Dátum formátum átalakítása (YYYY-MM-DD-ről DD/MM/YYYY-re):
    • Szöveg: "A mai dátum 2023-10-26."
    • Keresési minta: (\d{4})-(\d{2})-(\d{2})
    • Csereszöveg: $3/$2/$1
    • Eredmény: "A mai dátum 26/10/2023."

Reguláris Kifejezések Programozási Nyelvekben

A reguláris kifejezések gyors és hatékony mintakeresést biztosítanak.
A reguláris kifejezések hatékonyan keresnek és módosítanak szöveget, széles körben alkalmazzák programozásban.

A reguláris kifejezések szinte minden modern programozási nyelv alapvető részét képezik. Bár a szintaxisuk hasonló, az API-k és a függvénynevek nyelvenként eltérőek lehetnek.

Python (re modul)

A Python beépített re modulja biztosítja a reguláris kifejezések funkcionalitását.


import re

szoveg = "A macska ül a szőnyegen. A kutya alszik."

# Keresés
minta = "macska"
talalat = re.search(minta, szoveg)
if talalat:
    print(f"'{minta}' megtalálható a szövegben a {talalat.start()}-{talalat.end()} pozíción.")
    # Eredmény: 'macska' megtalálható a szövegben a 2-8 pozíción.

# Összes illeszkedés megtalálása
minta_all = r"\b[aA]\w+\b" # Szavak, amik 'a' vagy 'A' betűvel kezdődnek
talalatok = re.findall(minta_all, szoveg)
print(f"Az illeszkedő szavak: {talalatok}")
# Eredmény: Az illeszkedő szavak: ['A', 'alszik']

# Csere
csere_minta = r"macska"
csere_szoveg = r"kutya"
uj_szoveg = re.sub(csere_minta, csere_szoveg, szoveg)
print(f"Eredeti: '{szoveg}'\nÚj: '{uj_szoveg}'")
# Eredmény: Eredeti: 'A macska ül a szőnyegen. A kutya alszik.'
#          Új: 'A kutya ül a szőnyegen. A kutya alszik.'

# Csoportok és flag-ek
szamok = "Telefonszám: +36 (20) 123-4567"
minta_szam = r"(\+\d{1,3})\s*\(?(\d{2})\)?\s*(\d{3})[-.\s]?(\d{4})"
talalat_szam = re.search(minta_szam, szamok)
if talalat_szam:
    print(f"Teljes szám: {talatat_szam.group(0)}")
    print(f"Országkód: {talalat_szam.group(1)}")
    print(f"Körzetszám: {talalat_szam.group(2)}")
    print(f"Első 3 számjegy: {talalat_szam.group(3)}")
    print(f"Utolsó 4 számjegy: {talalat_szam.group(4)}")
# Eredmény: Teljes szám: +36 (20) 123-4567
#          Országkód: +36
#          Körzetszám: 20
#          Első 3 számjegy: 123
#          Utolsó 4 számjegy: 4567

email_lista = "janos@example.com, anna@domain.hu, peti@mail.net"
email_minta = r"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})"
talalt_emailek = re.findall(email_minta, email_lista)
print(f"Talált e-mailek: {talalt_emailek}")
# Eredmény: Talált e-mailek: ['janos@example.com', 'anna@domain.hu', 'peti@mail.net']

# Flag-ek használata
szoveg_case = "Ez egy Teszt szöveg."
minta_case = "teszt"
# Case-érzéketlen keresés
talalat_case_ins = re.search(minta_case, szoveg_case, re.IGNORECASE)
if talalat_case_ins:
    print(f"Case-érzéketlenül megtalálva: {talalat_case_ins.group(0)}")
# Eredmény: Case-érzéketlenül megtalálva: Teszt

JavaScript (RegExp objektum és String metódusok)

JavaScriptben a reguláris kifejezések literális szintaxissal (/minta/flags) vagy a RegExp konstruktorral hozhatók létre. A String objektum több metódust is kínál regex alapú műveletekhez.


const szoveg = "A macska ül a szőnyegen. A kutya alszik.";

// Keresés (String.prototype.search)
const minta1 = /macska/;
const index = szoveg.search(minta1);
console.log(`'macska' megtalálható az indexen: ${index}`);
// Eredmény: 'macska' megtalálható az indexen: 2

// Összes illeszkedés megtalálása (String.prototype.matchAll - ES2020)
// Vagy régebbi módon: String.prototype.match és a 'g' flag
const minta2 = /\b[aA]\w+\b/g; // 'g' flag a globális kereséshez
const talalatokIterator = szoveg.matchAll(minta2);
const talalatokArray = Array.from(talalatokIterator).map(match => match[0]);
console.log(`Az illeszkedő szavak: ${talalatokArray}`);
// Eredmény: Az illeszkedő szavak: A,alszik

// Csere (String.prototype.replace)
const csereMinta = /macska/;
const csereSzoveg = "kutya";
const ujSzoveg = szoveg.replace(csereMinta, csereSzoveg);
console.log(`Eredeti: '${szoveg}'\nÚj: '${ujSzoveg}'`);
// Eredmény: Eredeti: 'A macska ül a szőnyegen. A kutya alszik.'
//          Új: 'A kutya ül a szőnyegen. A kutya alszik.'

// Csoportok és flag-ek
const szamok = "Telefonszám: +36 (20) 123-4567";
const mintaSzam = /(\+\d{1,3})\s*\(?(\d{2})\)?\s*(\d{3})[-.\s]?(\d{4})/;
const talalatSzam = szamok.match(mintaSzam); // match() visszaadja a csoportokat is
if (talalatSzam) {
    console.log(`Teljes szám: ${talalatSzam[0]}`);
    console.log(`Országkód: ${talalatSzam[1]}`);
    console.log(`Körzetszám: ${talalatSzam[2]}`);
    console.log(`Első 3 számjegy: ${talalatSzam[3]}`);
    console.log(`Utolsó 4 számjegy: ${talalatSzam[4]}`);
}
// Eredmény: Teljes szám: +36 (20) 123-4567
//          Országkód: +36
//          Körzetszám: 20
//          Első 3 számjegy: 123
//          Utolsó 4 számjegy: 4567

// Flag-ek használata
const szovegCase = "Ez egy Teszt szöveg.";
const mintaCase = /teszt/i; // 'i' flag a case-érzéketlenséghez
const talalatCaseIns = szovegCase.match(mintaCase);
if (talalatCaseIns) {
    console.log(`Case-érzéketlenül megtalálva: ${talalatCaseIns[0]}`);
}
// Eredmény: Case-érzéketlenül megtalálva: Teszt

PHP (preg_ függvények)

PHP-ban a PCRE (Perl Compatible Regular Expressions) függvények (prefix preg_) a reguláris kifejezések kezelésére szolgálnak.


<?php
$szoveg = "A macska ül a szőnyegen. A kutya alszik.";

// Keresés (preg_match)
$minta1 = "/macska/";
if (preg_match($minta1, $szoveg, $matches)) {
    echo "'macska' megtalálható a szövegben.\n";
    // $matches[0] tartalmazza a teljes illeszkedést
}
// Eredmény: 'macska' megtalálható a szövegben.

// Összes illeszkedés megtalálása (preg_match_all)
$minta2 = "/\\b[aA]\\w+\\b/"; // Kettős backslash szükséges PHP stringben
preg_match_all($minta2, $szoveg, $matches_all);
echo "Az illeszkedő szavak: " . implode(", ", $matches_all[0]) . "\n";
// Eredmény: Az illeszkedő szavak: A, alszik

// Csere (preg_replace)
$csereMinta = "/macska/";
$csereSzoveg = "kutya";
$ujSzoveg = preg_replace($csereMinta, $csereSzoveg, $szoveg);
echo "Eredeti: '{$szoveg}'\nÚj: '{$ujSzoveg}'\n";
// Eredmény: Eredeti: 'A macska ül a szőnyegen. A kutya alszik.'
//          Új: 'A kutya ül a szőnyegen. A kutya alszik.'

// Csoportok és flag-ek
$szamok = "Telefonszám: +36 (20) 123-4567";
$mintaSzam = "/(\\+\\d{1,3})\\s*\\(?(\\d{2})\\)?\\s*(\\d{3})[-.\\s]?(\\d{4})/";
if (preg_match($mintaSzam, $szamok, $talalatSzam)) {
    echo "Teljes szám: {$talalatSzam[0]}\n";
    echo "Országkód: {$talalatSzam[1]}\n";
    echo "Körzetszám: {$talalatSzam[2]}\n";
    echo "Első 3 számjegy: {$talalatSzam[3]}\n";
    echo "Utolsó 4 számjegy: {$talalatSzam[4]}\n";
}
// Eredmény: Teljes szám: +36 (20) 123-4567
//          Országkód: +36
//          Körzetszám: 20
//          Első 3 számjegy: 123
//          Utolsó 4 számjegy: 4567

// Flag-ek használata (a minta után)
$szovegCase = "Ez egy Teszt szöveg.";
$mintaCase = "/teszt/i"; // 'i' flag a case-érzéketlenséghez
if (preg_match($mintaCase, $szovegCase, $talalatCaseIns)) {
    echo "Case-érzéketlenül megtalálva: {$talalatCaseIns[0]}\n";
}
// Eredmény: Case-érzéketlenül megtalálva: Teszt
?>

Java (java.util.regex)

Java-ban a java.util.regex csomag biztosítja a reguláris kifejezések funkcionalitását a Pattern és Matcher osztályokkal.


import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexDemo {
    public static void main(String[] args) {
        String szoveg = "A macska ül a szőnyegen. A kutya alszik.";

        // Keresés
        Pattern minta1 = Pattern.compile("macska");
        Matcher matcher1 = minta1.matcher(szoveg);
        if (matcher1.find()) {
            System.out.println("'macska' megtalálható a szövegben.");
        }
        // Eredmény: 'macska' megtalálható a szövegben.

        // Összes illeszkedés megtalálása
        Pattern minta2 = Pattern.compile("\\b[aA]\\w+\\b"); // Kettős backslash szükséges Java stringben
        Matcher matcher2 = minta2.matcher(szoveg);
        System.out.print("Az illeszkedő szavak: ");
        while (matcher2.find()) {
            System.out.print(matcher2.group() + " ");
        }
        System.out.println();
        // Eredmény: Az illeszkedő szavak: A alszik

        // Csere
        Pattern csereMinta = Pattern.compile("macska");
        String csereSzoveg = "kutya";
        String ujSzoveg = csereMinta.matcher(szoveg).replaceAll(csereSzoveg);
        System.out.println("Eredeti: '" + szoveg + "'\nÚj: '" + ujSzoveg + "'");
        // Eredmény: Eredeti: 'A macska ül a szőnyegen. A kutya alszik.'
        //          Új: 'A kutya ül a szőnyegen. A kutya alszik.'

        // Csoportok és flag-ek
        String szamok = "Telefonszám: +36 (20) 123-4567";
        Pattern mintaSzam = Pattern.compile("(\\+\\d{1,3})\\s*\\(?(\\d{2})\\)?\\s*(\\d{3})[-.\\s]?(\\d{4})");
        Matcher talalatSzam = mintaSzam.matcher(szamok);
        if (talalatSzam.find()) {
            System.out.println("Teljes szám: " + talalatSzam.group(0));
            System.out.println("Országkód: " + talalatSzam.group(1));
            System.out.println("Körzetszám: " + talalatSzam.group(2));
            System.out.println("Első 3 számjegy: " + talalatSzam.group(3));
            System.out.println("Utolsó 4 számjegy: " + talalatSzam.group(4));
        }
        // Eredmény: Teljes szám: +36 (20) 123-4567
        //          Országkód: +36
        //          Körzetszám: 20
        //          Első 3 számjegy: 123
        //          Utolsó 4 számjegy: 4567

        // Flag-ek használata (Pattern.compile második paramétereként)
        String szovegCase = "Ez egy Teszt szöveg.";
        Pattern mintaCase = Pattern.compile("teszt", Pattern.CASE_INSENSITIVE);
        Matcher talalatCaseIns = mintaCase.matcher(szovegCase);
        if (talalatCaseIns.find()) {
            System.out.println("Case-érzéketlenül megtalálva: " + talalatCaseIns.group());
        }
        // Eredmény: Case-érzéketlenül megtalálva: Teszt
    }
}

Tippek és Bevett Gyakorlatok

A reguláris kifejezések elsajátítása időt és gyakorlatot igényel. Az alábbi tippek segíthetnek a hatékonyabb használatban:

1. Használj Online Regex Tesztelő Eszközöket

Számos kiváló online eszköz létezik, amelyek valós időben tesztelik a reguláris kifejezéseket a megadott szövegen. Ezek vizuálisan is kiemelik az illeszkedéseket és a rögzített csoportokat, ami felgyorsítja a hibakeresést és a tanulási folyamatot. Néhány népszerű: regex101.com, regexr.com, regextester.com.

2. Kezdd Egyszerűen, Aztán Bonyolítsd

Ne próbáld meg azonnal a tökéletes, komplex reguláris kifejezést megírni. Kezdd egy egyszerű mintával, amely a leglényegesebb részekre illeszkedik, majd fokozatosan add hozzá a részleteket, a kvantifikátorokat, a csoportokat és a horgonyokat.

3. Légy Specifikus, Ha Lehetséges

A túl általános minták (pl. .*) gyakran több illeszkedést találnak, mint amit szeretnénk, és teljesítményproblémákat is okozhatnak. Használj specifikusabb karakterosztályokat (\d, \w, [a-z]) és kvantifikátorokat ({n}, +) a pontosabb illesztés érdekében.

4. Légy Tudatában a Mohó (Greedy) Viselkedésnek

Ahogy korábban említettük, a kvantifikátorok alapértelmezés szerint mohók. Ha nem a teljes szövegre, hanem a legkisebb lehetséges illesztésre van szükséged, használd a nem-mohó (lazy) változatot (pl. *?, +?, ??).

5. Használj Nem-rögzítő Csoportokat ((?:...))

Ha csak csoportosítani szeretnél, de nem érdekel az adott rész illesztésének rögzítése, használd a (?:...) szintaxist. Ez javíthatja a teljesítményt és tisztábbá teszi a visszahivatkozások számozását.

6. Kommenteld a Komplex Reguláris Kifejezéseket

A komplex reguláris kifejezések rendkívül nehezen olvashatók lehetnek utólag. Használd a bőbeszédű (x) flag-et, és kommentáld a minta egyes részeit. Vagy legalább a kódban, a regex mellé írj magyarázatot.


# Példa Pythonban, kommenttel a kódban
# Minta egy IPv4 címre
# ^                     # Sor eleje
# (?:                   # Nem-rögzítő csoport a 4 oktetnek
#   \d{1,3}             # Egy-három számjegy (oktet)
#   \.                  # Pont elválasztó
# ){3}                  # Ismételje 3-szor
# \d{1,3}               # Utolsó oktet
# $                     # Sor vége
ipv4_pattern = r"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
# Ez a minta már a számok érvényességét is ellenőrzi (0-255)

7. Ne Használd Regexet, Ha Nem Muszáj

Bár a reguláris kifejezések erőteljesek, nem minden szövegkezelési feladatra alkalmasak. Egyszerű string műveletekre (pl. egy karakterlánc ellenőrzése, hogy tartalmaz-e egy másik karakterláncot) gyakran hatékonyabbak és olvashatóbbak a beépített string metódusok (pl. .contains(), .startsWith(), .endsWith(), .split()).

8. Teljesítmény Megfontolások (ReDoS)

A komplex reguláris kifejezések, különösen ha kvantifikátorokat és beágyazott csoportokat tartalmaznak, Exponenciális Hátrakövetés (Catastrophic Backtracking) jelenséghez vezethetnek bizonyos bemenetek esetén. Ez egyfajta DoS (Denial of Service) támadás, amit ReDoS (Regular Expression Denial of Service)-nek neveznek. Ez akkor fordul elő, ha a regex motor túl sok lehetséges illesztési útvonalat próbál ki, ami rendkívül lelassíthatja a programot. Kerüld az olyan mintákat, mint (a+)+ vagy (.*a){10}, ha nem vagy teljesen biztos a bemenetben. Használj atomic grouping-ot ((?>...)) vagy posszív kvantifikátorokat (*+, ++, ?+), ha a regex motor támogatja, hogy megakadályozd a hátrakövetést.

A reguláris kifejezések a modern szövegfeldolgozás és adatelemzés egyik legfontosabb és leguniverzálisabb eszközei, amelyek megfelelő alkalmazásával rendkívül komplex mintakeresési és -kezelési feladatok automatizálhatók hatékonyan és rugalmasan.

Haladó Témák (Röviden)

A reguláris kifejezések világa rendkívül mély, és a fent bemutatott alapokon túl számos haladó funkció is létezik, amelyek még nagyobb rugalmasságot biztosítanak. Ezek implementációja nagymértékben függ a használt regex motortól (pl. PCRE, .NET, Java).

Rekurzív Kifejezések

Bizonyos regex motorok (különösen a PCRE, amit a PHP és Perl használ) támogatják a rekurzív kifejezéseket. Ez lehetővé teszi, hogy egy minta illeszkedjen önmagára, ami például beágyazott zárójelek vagy HTML/XML tag-párok (korlátozott) illesztésére használható. Példa: \(([^()]*|(?R))*\) illeszkedik a beágyazott zárójelekre.

Atomic Grouping ((?>...))

Az Atomic Grouping egy fejlett funkció, amely segít elkerülni a katasztrofális hátrakövetést (ReDoS). Amikor a regex motor belép egy atomi csoportba, és illeszkedik egy részre, akkor az adott csoporton belül már nem fog visszafelé lépkedni (backtrack-elni), még akkor sem, ha ez a teljes illesztést meghiúsítja. Ez javítja a teljesítményt és a biztonságot a rosszindulatú bemenetek ellen.

  • Példa: A (?>a+)b minta sosem illeszkedik "aaab" szövegre, ha az "a" után nincs "b", mert az a+ mohón illeszkedik az összes "a"-ra, és nem adja vissza az "a" karaktereket, hogy a "b" illeszkedhessen. Ez megakadályozza a hátrakövetést.

Conditional Expressions ((?(condition)yes-pattern|no-pattern))

A feltételes kifejezések lehetővé teszik, hogy a minta különbözőképpen viselkedjen egy feltételtől függően. A feltétel lehet például egy korábban rögzített csoport létezése vagy egy előretekintő állítás.

  • Példa: (A)?B(?(1)C|D)
    • Ha az "A" illeszkedik (az 1. csoport rögzítésre kerül), akkor "C"-nek kell követnie (pl. "ABC").
    • Ha az "A" nem illeszkedik, akkor "D"-nek kell követnie (pl. "BD").

Ezek a haladó funkciók tovább növelik a reguláris kifejezések erejét és rugalmasságát, de bonyolultabbá teszik a minták megértését és hibakeresését. Általában csak akkor érdemes használni őket, ha az egyszerűbb megoldások nem elegendőek.

Share This Article
Leave a comment

Vélemény, hozzászólás?

Az e-mail címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük