Reguláris kifejezések 1. A nyelvtechnológia eszközei és nyersanyagai 1. gyakorlat A beadandó feladatok be vannak keretezve! 1.1. Miért hívják reguláris kifejezésnek? (!) Az elméleti és a gyakorlati reguláris kifejezés valóban ugyanaz. (!) A reguláris kifejezések tényleg kifejezések. Def.: nyelv = abc fölötti string-halmaz Megj.: nyelvek közti műveletek pl.:,,, *,... Def.: reguláris nyelv = nyelvek legszűkebb halmaza, mely zárt a konkatenáció, unió, lezárás műveletekre. Def.: reguláris kifejezés = az Σ elemein kívül, csak (,),*, és spec. szimbólumokat tartalmazhatja Megj.: Definiálható olyan függvény, ami minden reg.kif-hez egy reg. nyelvet rendel hozzá. reguláris nyelvtan reguláris kifejezés véges automata mindhárom egy reguláris nyelvet ad meg. nyelv művelet nyelv = új nyelv Pl.: a, b, c ez három (egyelemű!) nyelv a konkat b = ab a unió b = a, b (jele: a b ) lezár a =, a, aa, aaa,... (jele: a* ) a* konkat b = b, ab, aab,... Az a*b (lezár a ) konkat b pontosan olyan kifejezés, mint az (5 * 4 + 2)/11. Sok további hasznos művelet van: http://www.cis.upenn.edu/ cis639/docs/fssyntax.html Innen indult, az igények szerint továbbfejlődött, kiterjesztették, a név rajtaragadt, pedig most már nem feltétlenül reguláris nyelvet ír le. 1
Elemek és rövidítések : atom: alapból az ábécé elemei, karakterek konkatenáció: egymás mellé írás unió:. [0-9] [ˆ0-9]? d w s lezárás: * + {n,m} 1/1 Utóbbiakat hogyan lehet levezetni a három alapműveletből? Kiterjesztések: horgony: ˆ $ sor-orientáltság miatt lett. b szóhatár. memória: () 1, ez az, ami kilép a reguláris osztályból! Mit kell -sel védeni : [ˆ$.?*+() és persze, valamint [] -n belül: ]-ˆ A regkif nyelvjárások közül az extended változatot fogjuk használni: sed -r illetve egrep (vagy grep -E ) Mit jelentenek az alábbiak? [.] \** ^[*]+$ ^\*+$ ^# ^$ <([^>]+)>alma</\1> *.*.{1,8}\..{3} \(\d+ \+ \d+\) \/ \d+ b[ae]n\b ^(van lesz nincs) 1/2 Három azonos jelből álló szavakat tartalmazó nyelv hogyan írható le reguláris kifejezéssel? Reguláris ez a nyelv? 1.2. Írj reguláris kifejezést! Itt lehet kipróbálni: http://regexpal.com/ biztonságos jelszó (legalább 6 karakter, tartalmaz nagybetűt, kisbetűt, számot) 2
szavak, melyek betűi abc sorrendben vannak a n ba n mondatvégi pont fájl elérési útja ITK-s email cím 2000-nél kisebb betűvel írt számokra Bónusz: angol befejezett jelen idejű mondatok 3-mal osztható bináris számok 1.3. Környezet keresés: cat f egrep "regkif" cserélés: cat f sed -r "s/regkif/csere/gi" több csere egymás után: "s///;s///..." tesztfájl: 01.txt 1.4. Keresős feladatok: grep Írj olyan egysoros scriptet, ami... a home könyvtáradban lévő mindenki számára olvasható fájlokat írja ki (ls).bash_history-ból a home könyvtárba váltó parancsokat írja ki a nev.txt fájlból az első 6 névre illeszkedik Idézet a man grep -ből: Email bug reports to bug-gnu-utils@gnu.org. Be sure to include the word "grep" somewhere in the "Subject:" field. Milyen regkiffel válogatják szét a leveleket? Név variációi: M[ou]?am+[ae]r.*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Miért m+? Helyette mit lehetne? Mi a szerepe a.* -nak? Emailcím-felismerés: Nézd meg az alábbi kifejezést a tesztfájlon! 3
{[\w\.]+@[^\.@]+\.[^\.@]+(\.[^\.@]+)*} Mi a hiba? Javítsd ki! 1/3 Rövidíteni a kifejezést + két/három karakterre korlátozni a domain-t + elemezni, milyen címeket nem fed le a kifejezés Időpont: ([01][0-9] 2[0-3]):[0-5][0-9] Mit kell változtatni, hogy 8:05-re is jó legyen? Írj regkif-et a hónapnevekre! Teszteld! 1/4 Írj regkif-et, ami az írott szövegben található időpontok minél nagyobb halmazát lefedi: tegnap, december 5-én, holnap fél 5-kor, 6-án 12:57-kor stb. 1.5. Mit jelentenek az alábbiak? s/ */ /g s/^m//g s/[ \t]+$// s/ ([.,:;?!]+)/\1/g s/^\"(.*)\"/\1/ s/^\"([^"]*)\"/\1/ 1/5 Valós problémafelvetés, amihez valóban jó lenne adott regkif többszöri rekurzív alkalmazása. (!) A regkif-ek mindig a lehető leghosszabb stringre illeszkednek. 1.6. Cserélős feladatok: sed Tesztfájl: sed_test.txt Javítás környezet alapján (minden helytelen a névelőt az -ra): Nézd meg az alábbi regkif-et a tesztfájlon! s/( +)a( +)([bcdfghjklmnpqrstyxvw][a-z]*)/\1az\2\3/gi 4
Mi a hiba? Hogy lehetne azt elérni, hogy a sor elején lévő a-t is cserélje? Az avajat rosszul van írva, javítsd sed segítségével! Nézd meg az eredeti regkif-et a javított inputon! Mit tapasztalsz? Időpont átalakítása: s/([01][0-9] 2[0-3]):([0-5][0-9])/ 1. 2/ Példa a való világból. ebből: 1 MM Reguláris kifejezések 02.14. 2 PG Lexikográfia 02.21. ezt: <li><span class="date">2007-02-14</span><a href="ea/nyeny07_ea_1.ppt"> Reguláris kifejezések</a> (MM)</li> <li><span class="date">2007-02-21</span><a href="ea/nyeny07_ea_2.ppt"> Lexikográfia</a> (PG)</li> ezzel: s/ *([0-9]*) ([^ ]*) *(.*[^ ]) *0(.).(..).*/<li><span class="date"> 2007-0\4-\5<\/span><a href="ea\/nyeny07_ea_\1.ppt">\3<\/a> (\2)<\/li>/gc A harmadik zárójelben minek van a végén a [ˆ ]? Feltéve, hogy kétjegyű sorszámok is vannak, hogy lehet második lépésben szükség esetén nullával kitölteni az első helyet? 1/6 Hogy lehet ezt egy lépésben megcsinálni? Irodalom Jeffrey E. F. Friedl: Reguláris kifejezések mesterfokon Daniel Jurafsky & James H. Martin: Speech and Language Processing HF 1. Írj reguláris kifejezést, amivel lebegőpontos számokat lehet felismerni! 2. Írj regkif-et, amivel ISO-8601 extended format (google!) szerinti dátumokat lehet felismerni! 3. Tegyél linket a neved minden előfordulására a honlapodra! Pl.: A Peti A <a href=http://digitus.itk.ppke.hu/ peti>peti</a> 5