Pěkný prográmek na experimentování s perlovými regulárními výrazy (a na zjišťování, co si o sobě ten zatracený regulární výraz myslí, že nematchuje ;-) udělal Jura Polcar: http://www.physics.muni.cz/~polcar/tore/
Je to zatím verze 0.1, ale na blbnutí je to dobrý. Použití:
./tore.pl <nějaký_text
(místo přesměrování taky můžete text napsat a ukončit Ctrl-D). Pak píšete regulární výrazy a on vypisuje co se matchlo, do který skupiny, etc.
Potreboval jsem zformatovat vystup z prikazu mpls na ftp klientovi (stahne mi to strukturu ftp do textoveho souboru). Pomoci regularnich vyrazu jsem si s tim pekne pohral, ale problem je ten ze zformatovani 50MB (cele to funguje jako prohledavac ftp serveru na koleji) textovych informaci trva hrozne dlouho. Na mem Duronu 1.1 GHz neco pres hodinu. zkousel jsem spoustet vice procesu najednou,ale pak se na pocitaci nedalo pracovat. Zajimalo by me tedy, zda je nejaka moznost jak to urychlit,bylo by to rychlejsi mit to napsane v C?
Jinak mi moc pomohl serial regularni vyrazy v minulosti uverejneny na rootovi.
sice nevim, co to to mpls je, ale to asi neni dulezite. kdyz je neco pomale, tak urcite pomuze napsat tomu program "na miru"... Regularni vyrazy jsou dost obecne reseni a proto se za ne plati pomalosti (i kdyz to je kdovijak optimalizovane)...
Taky je dobre v reg. vyrazech pocitaci nejak ulehcit Hned na zacatku promaznout vsechno, co neni treba, aby se tim nemusel zbytecne zabyvat a zmensil se objem dat, lepe formulovat vyrazy a podobne.
Pokud to je vazne dulezite, rozhodne by stalo za to to v nejakem jazyku prepsat bez (nebo jen s minimalnim) pouzitim regularnich vyrazu. (Kdyz uz ne v C, tak alespon v Perlu, PHP...)
vsechny prikazy delam v bashi:
zkusim tady vlozit zdrojak ale nekamenujte mne za moje programatorske schopnosti,nejsem programator :)
takto vypada nenaformatovany text:
/d:/My Music/Alba/Clawfinger:
total 397792
-rw-rw-rw- 1 user group 1622 May 27 2002 !Clawfinger.m3u
---------- 1 user group 4696317 Jun 27 2000 Back To The Basics.mp3
a takto naformatovany:
HSTNAME/d:/My Music/Alba/Clawfinger/!Clawfinger.m3u 1622 27 01 2003 09:47:54
HOSTNAME/d:/My Music/Alba/Clawfinger/Back To The Basics.mp3 4696317 27 01 2003 09:47:54
a toto je ten skript:
#!/bin/bash
#cesta=/ #promenna cesta #nakonec zbytecne
datum=`date '+%d %m %Y %T'`
sed -e s/:$//g ./ftpseznam/$1 > temp #odstrani : na konci radky
sed -e /^total\ \[0-9]/d temp >temp2 #odstrani zbytecnost o total cislo
sed -e 's/\([^ ]*[ ][ ]*\)\{4\}\([^ ]*\)[ ][ ]*\([^ ]*\)[ ][ ]*\([^ ]*\)[ ][ ]*\([^ ]*\)[ ][ ]*\(.*\)/\6 \2/' temp2 >temp
#spocitat pocet radku souboru
pocet=`wc -l temp | cut -c0-7`
#echo $pocet
for i in $(seq 1 $pocet)
do
radek=`sed ''$i'q;d' temp` #2X RYCHLEJSI !!!
#echo "$radek"
if [ -z "$radek" ] #pokud je radek prazdny, vzdy kdyz nasleduje cesta
then
#echo PRAZDNY #zde posun o jedno dolu ++i ;nacteni cesty do promenne; --i;
i=`expr $i + 1`
radek=`sed ''$i'q;d' temp`
cesta=$radek
#echo $radek #je to zbytecne tento radek se opakuje i jako soubor
i=`expr $i + 1`
else
x=$radek # pri primem dosazeni mi to blblo
y=$cesta
if [ "$x" != "$y" ]
then
#echo tento radek NECHAT
echo $1$cesta/$radek $datum>>./ftpformat/$1
#echo $1/$cesta/$radek
fi
fi
done
zkuste regexplorer
jinak, i presto, ze regularni vyrazy skoro denne pouzivam, neco jsem pomoci nich napsal a sleduju mimo jine clanky na rootu, presto se me znich dela porad spatne a desi me predstava delat s nimi cokoli slozitejsiho, je to skutecne prave peklo co kdo vymyslel, pripodobnil bych to snad jedine ke asembleru, des a hruza na nas z regularnich vyrazu cisi...
Jen drobnou pripominku k teto vete vyskytujici se v clanku..."Ze všeho nejdříve si pro něj sestaví konečný (nejlépe deterministický, aby se dobral výsledku) automat."
Tu poznamku v zavorce nechapu. Deterministicke a nedeterministicke konecne automaty jsou ekvivalnentni. Nedeterministicke konecne automaty samozrejme take davaji vysledky (jinak by byly k nicemu), a ke kazdemu nedeterministickemu konecnemu automatu lze sestrojit trivialne deterministicky, ktery je co do prijimanych slov ekvivalentni puvodnimu nedeterministickemu.
Jojo, to je, ale sestevit nedeterm. automat pro regex je trivialni, kdezto determ. uz tak trivialni neni - teda, neni jednoducha implementace, teorie jednoducha je. Taky ma tato transformace jeden docela neprijemny hacek, prevodem z nedet. na det. roste exponencialne pocet stavu. Zkuste si treba vyraz (a|b)*a(a|b)^n, teda posloupnost acek a becek, kde n-ty znak pred koncem je acko. Zjistite, ze pocet stavu determ. automatu je neco kolem 2^n. V praxi se to dela tak, ze se automat ponecha nedeterministicky a hledani vzorku dat se provadi na nem, pricemz jeden stav je n-bitove cislo, kde n je pocet stavu onoho nedet. automatu. Je pak mozne jakoby byt ve vice stavech najednou - ve kterych to urcuji bity onoho n-bitoveho cisla. Prechodova funkce je snad zrejma ;-))))
Jen pro zajimavost, neni zase az tak uplne jednoduche prevest regex na prislusny automat, tedy na determ. automat. Dlouho jsem hledal vhodnou knihovnu (v cecku) a nenasel. Teda, nasel :-), ale uplne nahodou a v uplne jinem kontextu. Stahnete-li si squirm, je ve zdrojacich adresar regex-xx.xx a v nem velmi pekna knihovnicka (regex.c) asi 5000 radku a k tomu moc pekna dokumentace. Nemate-li co delat, prohlidku tohoto zdrojaku (minimalne dokumentace) muzu vrele doporucit, muze se to hodit ;-)
Rad bych pouzival regularky i mimo skriptovaci jazyky, vim ze jsou ruzne knihovny pro pouziti v C++, Pascalu atd... Ale ty napred musi regularku naparsovat a pak teprve spusti hledani, takze pro velka data jsou pomalejsi
Jedna se mi o generator, do ktereho bych zadal regularni vyraz a on vyplivl kratky kod v C++ , ktery pouziva standartni retezcove funkce. O necem takovem jsem slysel, ale za boha to nemuzu najit.
Priklad regularka 'aa' ->
if (strpos('aa',nejakystring)<>-1)
return true;
else
return false;
V článku mě dostal jeden z uvedených příkladů.
> Příklad: http://[a-zA-Z_.]+
> Tímto výrazem můžeme snadno nalézt webové
> odkazy. Jistě byste už dovedli zkonstruovat
> odkaz, který by například našel jen ty odkazy,
> které by nekončily řetězcem "asp".
Jako jeden regulární výraz? V článku jsem nenašel nic, co by mi to umožnilo.
"...(?!asp)$" by asi šlo v sedu, ale o tom v článku nic nebylo. Mohl bych taky vyjmenovat všechny tříznakové varianty (kromě asp) :-O
Nejde to nějak snadno? Autor článku se tváří, jako by to bylo to nejjednodušší na světě.
(Ještě to jde vícero výběrama...
egrep -v "asp$" | egrep "...")