Strona 1 z 2 12 OstatniOstatni
Pokaż wyniki 1 do 10 z 19

Temat: [Perl] Kurs Perl - cz.3 - wyrazenia regularne, formaty, hashe...

  1. #1
    Zarejestrowany
    Jun 2006
    Skąd
    rand(.eu)
    Postów
    8,748

    Domyślnie [Perl] Kurs Perl - cz.3 - wyrazenia regularne, formaty, hashe...

    Hej!

    Jak ten czas szybko leci... no wiec z tygodniowym opoznieniem i 6 serwerow dalej... lecimy z nastepna czescia kursu

    Dzisiaj omowimy wyrazenia regularne - cos co jest jednym z najwiekszych skarbow w Perlu. Inne jezyki sa w tej kwestii dosc ubogie, od jakiegos czasu dopiero jest biblioteka libpcre, pcre to Perl Compatibile Regular Expressions (http://www.pcre.org/ hihi)... wiec widac skad takie cos sie wywodzi i gdzie zostalo to uzyte po raz pierwszy.
    Przy okazji kursu Javy zaczalem szukac czy do Javy sa regexy (tak potocznie sie je nazywa od 'regular expressions') no i w koncu sa... dluuugo nie bylo ale juz sa jako czesc pakietu java.util.* - niestety sa bardzo podstawowe (choc mozna oczywiscie korzystac z innych klas dostarczonych przez innych ludzi). PHP ma regexy (preg_match, preg_replace, itd) - roznia sie nieco skladnia polecenia ale generalnie beda podobne... Np egrep uzywa praktycznie identycznej skladni.

    Znaki uzywane w wyrazeniach regularnych
    Kod:
    ^ - oznacza poczatek linii/wiersza/zmiennej - ogolnie poczatek tekstu
    $ - j.w. tyle ze koniec
    . - dowolny znak (pojedyncza kropka)
    \w - tzw 'word' czyli zestaw A-Z, a-z, 0-9 oraz podkreslenie
    \W - non-word - przeciwienstwo tego co wyzej
    \s - znak bialy czyli spacja lub tabulacja
    \S - znak nie-bialy
    \d - cyfra (digit)
    \D - nie-cyfra
    itd... na razie sotaniemy przy tych. Temat wyrazen regularnych jest baaardzo szeroki - na tyle szeroki, ze sa do niego osobne ksiazki w ogole, wiec nie bedziemy za daleko tutaj sie zaglebiac.

    Zapis wyrazenia regularnego
    Na razie skupimy sie tylko na samym wyrazeniu, pozniej polaczymy je z kodem i zobaczymy jak dziala - tutaj zaczyna sie ogrom magii perla zwiazanej z analiza plikow tekstowych miedzy innymi. Wyrazenia bede zapisywal pomiedzy lamaniami / - tak jak to bedzie pozniej w kodzie - tak prosciej sie czyta.

    Kod:
    TEKST: 3 maja 2008 13:57:00 CET
    Wyrazenie: /^\d \w\w\w\w \d\d\d\d \d\d:\d\d:\d\d \w\w\w$/;
    Generalnie kaszana - niewygodne, nie skaluje sie itd... co by bylo gdyby byla data "01 kwietnia 2008" albo wiecej spacji miedzy elementami? Tego juz wyrazenie regularne nie zlapie... w takim razie trzeba jakos opisac ilosc znakow, dlugosc pol... a moze po prostu napisac ze, ma byc kilka znakow?

    Wiecej znakow danego typu w wyrazeniu...
    Regexy sa bardzo elastyczne... napiszmy np:

    Kod:
    \d - jedna cyfra
    \d{1} - dokladnie jedna cyfra - jak wyzej
    \d+ - jedna lub wiecej cyfr
    \d{1,} - to samo
    \d* - zero lub wiecej cyfr
    \d{0,} - to samo
    \d{,3} - od 0 a 3 cyfry
    \d{2,5} - minimum 2 max 5 syfr
    Oczywiscie ten sam zapis mozna uzywac w przypadku innych dowolnych grup znakow opisanych jak przyklady wyzej lub doslownie jako grup okreslonych przez uzytkownika (to tez jest mozliwe)

    Kod:
    /^\d{1,2}\s+\w+\s+\d{4}\s+\d{2}:\d{2}:\d{2}/
    W tym wrazeniu dzien zapisalismy jako 1 lub 2 cyfry na poczatku tekstu, dalej 1+ znakow bialych (spacja, tabulacja), ciag word (tu nazwa miesiaca), dokladnie 4 cyfry (rok) i 3 dwucyfrowe czesci oznaczajace czas, nie interesuje nas dopasowanie nazwy strefy czasowej.

    Teraz lekko modyfikujemy to co mamy - interesuje nas wylapanie tylko i wylacznie czasu - bez tego co jest po bokach.

    Kod:
    /\d{2}:\d{2}:\d{2}/
    zauwazcie ze nie ma juz ^ na poczatku linii ani $ na koncu, poniewaz tekst ktory dopasowujemy jest w srodku i nie siega do koncow. Bardzmy teraz jeszcze bardziej leniwi hihi

    Kod:
    /(\d{2}:){2}\d{2}/
    Wlasnie skrocilismy pierwsze dwa bloki i kazalismy je powtorzyc 2 razy oraz dodalismy ostatni, po ktorym nie ma juz dwukropka. No to jeszcze inaczej

    Kod:
    m/(\S+)\s+(\w+)$/
    Wlasnie dopasowalismy czas i strefe czasowa czyli znaki inne niz biale, znak bialy (1 lub wiecej) i word oraz koniec stringa.

    Dopasowania "zachlanne" oraz tzw referencje wsteczne
    W ostatnich 2 przykladach pojawilo sie cos nowego - nawiasy! Maja one specjalne znaczenie, ktore moze byc rozne interpretowane zaleznie od kontekstu w jakim zostaly uzyte...

    Generalnie nawiasow uzywamy do grupowania wyrazen - tak jak 2 przyklad wyzej. Ostatni przyklad powyzej uzywa jednak nawiasow do tzw referencji wstecznych (jesli w ogole mozna to tak przetlumaczyc na polski).

    Wstawmy ostatniego regexa do kodu (z lekka modyfikacja) i zobaczmy co sie stanie - przyklad...

    Kod:
    #!/usr/bin/perl
    use strict;
    my $tekst = '3 maja 2008 14:47:00 BST";
    $tekst =~ m/(\S+)\s+(\w+)$/;
    print "Godzina to $1 w strefie $2\n";
    Ten przyklad zawiera 3 nowe rzeczy - po pierwsze operator =~, po drugie w regexie sa nawiasy ktore maja przechwycic wartosci zmiennych aby mozna je pozniej wyswietlic (to jest wlasnie 'backreference' ale nazywajmy je wynikiem dopasowania), po trzecie wykonalismy dopasowanie ktore nie jest zachlanne - to omowimy na koniec i pokazemy co to jest dopasownaie zachlanne i jak latwo mozna sie na nim 'przejechac' - co w sumie sam zrobilem piszac ta czesc hihi...

    C.D.N.

    EDIT - prosilem, ze jak pisze "C.D.N" to prosze nie wstawiac jeszcze swoich odpowiedzi bo bedzie ciag dalszy tej czesci...
    Ostatnio edytowane przez TQM : 05-03-2008 - 15:07
    ctrl-alt-del.cc - soft reset site for IT admins and other staff :-)

  2. #2
    Avatar GSG-9
    GSG-9 jest offline Shapeshifter
    Zarejestrowany
    Jul 2007
    Skąd
    C:\Perl\bin
    Postów
    1,578

    Domyślnie

    pierwszy!
    War, war never changes.

  3. #3
    Avatar gogulas
    gogulas jest offline killboy powerhead
    Zarejestrowany
    Sep 2007
    Skąd
    Tu
    Postów
    1,236

    Domyślnie

    juz chcialem napisac drugi, kiedy ten pierwszy tylko mi mignal gdy spadla nie niego kara boska :-]

    /edit
    Przepraszamy.
    Ostatnio edytowane przez gogulas : 05-03-2008 - 15:24
    http://gogulas.yoyo.pl/h.gif

  4. #4
    Avatar GSG-9
    GSG-9 jest offline Shapeshifter
    Zarejestrowany
    Jul 2007
    Skąd
    C:\Perl\bin
    Postów
    1,578

    Domyślnie

    Cytat Napisał gogulas Zobacz post
    spadla nie niego kara boska :-]
    na ten tez spadnie, nie boj sie


    @tqm
    cdn? czekamy, czekamy xD
    Ostatnio edytowane przez GSG-9 : 05-03-2008 - 15:23
    War, war never changes.

  5. #5
    Zarejestrowany
    Jun 2006
    Skąd
    rand(.eu)
    Postów
    8,748

    Domyślnie

    Zacznijmy od operatora =~ ktory oznacza ze operacje wykonujemy na zmiennej po lewej stronie. Po jego prawej stronie znajduje sie operacja jaka wykonujemy...

    m/<regex>/ - wykonuje dopasowanie wzorca wzgledem zmiennej. Jesli zapiszemy doslownie tak jak tutaj (pogrubione) to dopasowanie odbedzie sie wzgledem zmiennej $_ ktora pamietacie z poprzedniej czesci. W kodzie powyzej podalismy jednak inna zmienna - $tekst =~ m/regex/; czyli wykonujemy regex match (dopasowanie) na zmiennej $tekst.

    Wracajac do naszych nawiasow - regexy nie mialyby sensu gdyby nie dalo sie zwrocic wyniku dopasowania w jakis logiczny sposob, prawda? Tak wiec nawias tworza nam zmienne $1, $2 itd... ktore odpowiadaja temu co 'zlapalo sie' w danej czesci wyrazenia regularnego.

    Teraz ciekawostka - czym roznia sie te 3 regexy ponizej?

    Kod:
    $tekst =~ m/(\S+)\s+(\w+)$/;
    $tekst =~ m/maja\s+(.*)\s+(.*)$/;
    $tekst =~ m/maja\s+(.*?)\s+(.*)$/;
    ... no tak - roznia sie wyrazeniem oraz jednym znakiem (znak zapytania), jednak logiczna roznica jest kolosalna!

    Pierwszy regex:
    - $1 = '14:47:00'
    - $2 = 'BST'

    Drugi regex:
    - $1 = '2008 14:47:00'
    - $2 = 'BST'

    Trzeci regex:
    - $1 = '2008'
    - $2 = '14:47:00 BST'

    Wyrazenia zachlanne
    Zastosowanie * oznacza zero lub wiecej, pytanie wiec dokladnie ile oznacza 'wiecej'? Odpowiedz jest prosta - tyle ile sie da tak wiec w pierwszym przypadku .* oznacza wszystko ile sie da, tak wiec drugi regex dopasowuje w pierwszym nawiasie maksymalna ilosc dowolnych znakow (czyli .*) do czasu az natrafi na \s+, dalej ciag dowolnych znakow i koniec stringa. Dzieki temu drugi nawias lapie cokolwiek miedzy \s+ i koncem napisu, choc moze tam nic nie byc poniewaz .* oznacza zero lub wiecej znakow, nie okreslajac ich typu, wiemy jednak ze maja wystapic po jednym lub wiecej znakach bialych (\s+).

    To jest wlasnie przyklad zachlannego dopasowania. Wiem ze na razie jest to strasznie pokrecone ale w miare uzywania stanie sie na prawde dosc jasne.

    Trzeci regex ma dodany znak zapytania ktory niweluje zachlanne dzialanie dopasowan - .*? oznacza dopasuj zero lub wiecej dowolnych znakow do czasu az napotkasz... w naszym przypadku \s+ tak wiec dopasuje .*? dopasuje nam tylko 2008 i zakonczy dopasowanie gdy napotka znak bialy. W ten sposob $2 dopasowalo nam cala reszte - dopasowanie zachlanne.

    Pozniej postaram sie podac wiecej przykladow (na pewno ich nieco pokaze) jednak na razie musicie zapamietac, ze .* bedzie dopasowywac ile sie da... a .*? tylko do czasu napotkania nastepnego elementu opisanego w regexie, cokolwiek to nie bedzie.

    Gdzie uzywamy regexow?
    Regexy sa idealnym narzedziem do rozwiazywania wielu problemow - np mozemy odfiltrowac wszystkie zakomentowane linie z pliku:
    Kod:
    #!/usr/bin/perl
    while (<>) {
      /^#/ ? next : print;
    }
    i teraz uruchamiamy nasz skrypt jako filtr:
    Kod:
    cat skrypt.sh | filtr.pl > skrypt-no_comments.sh
    Powyzsza petla czyta STDIN i pisze na STDOUT. Jedyne co zapisalem w petli to if (/^#) { next } else {print} tyle ze w ktorkiej wersji. Jak widzicie nie napisalem m/<regex>/ tylko /<regex>/ - domyslnie sa one sobie rownowazne... a sam kod programu mozna zapisac i uruchomic na co najmniej kilka innych sposobow, chocby nawet wpisac w jednym wierszu w linii polecen ale nie bedziemy wiecej gmatwac.

    Co z podstawieniami tekstu?
    Wlasnie trafilismy w sedno sprawy... przeszukiwanie stringow w poszukiwaniu wzorcow to jedno, ale co jesli chcemy na przyklad zastapic wszysktie litery 'a' czyms innym albo jesli chcemy zastapic kazde wystapienie 'a href' na 'A HREF' albo zrobic proste szyfrowani ROT-13? To wszystko robi sie w perlu w 1 linii doslownie.

    m/regex/ - dopasuj regex
    s/wzor/nowy_tekst/ - zastap napis 'wzor' napisem 'nowy_tekst'
    tr/a-z/A-Z/ - zamien wszystki emale litery na duze litery
    tr/01/10/ - przekonwertuj wszystkie zera na jedynki i jedynki na zera

    roznica miedzy tr/// a s/// jest taka, ze s/// operuje na stringu i podmienia cale ciagi (np s/CET/BST/ zamieni wszystkie wystapienia napisu CET na BST) a tr/// operuje na znakach (tr/CET/BST/ zamieni C na B, E na S i T na T hihi).

    Modyfikatory
    m/regex/m - tekst moze rozciagac sie na wiele linii, wiec ^ i $ zmieniaja swoje znaczenie - zamiast dopasowywac poczatek i koniec stringu oznaczaja poczatek i koniec kazdej linii w stringu
    m/regex/s - traktuj string jak jedna linie - w tym wypadku . dopasuje rowniez znak konca linii
    m/regex/i - dopasowanie bez zwracania uwagi na wielkosc liter (domyslnie wielkosc liter ma znaczenie)

    Modyfikatorow jest wiecej a sam temat jest o wiele bardziej zawily niz to tutaj przedstawilem - na razie ledwie zarysowalismy powierzchnie, jednak to wystarczy nam na razie... przynajmniej do napisania prostych aplikacji.

    Wiecej informacji o wyrazeniach regularnych mozna znalezc w manualu (perldoc perlre albo man perlre albo http://perldoc.perl.org/perlre.html) a informacje o specyficznych modyfikatorach dla s/// i tr/// w sekcji perlop manuala do perla (man perlop) lub http://perldoc.perl.org/perlop.html

    Na razie jednak tyle nam wystarczy i zaraz zrobimy sobie klasyczny przyklad - pobawimy sie plikiem /etc/passwd hihi...

    C.D.N


    Na razie zostawimy temat tak jak jest - nie bede na sile wstawial przykladow, przyklady beda dalej i po kolei bedziemy uzywac tego co wlasnie pokazalem.
    ctrl-alt-del.cc - soft reset site for IT admins and other staff :-)

  6. #6
    Zarejestrowany
    Jun 2006
    Skąd
    rand(.eu)
    Postów
    8,748

    Domyślnie

    To to by bylo na tyle - koniec tej czesci kursu... kiedy bedzie nastepna - nie wiem. Prosilem o nie wrzucanie postow (zwlaszcza tak durnych jak te 3 powyzej ktore skasowalem) gdy na koncu jest napisane jak wol C.D.N.

    W ten sposob tylko zaciemniacie czytajacym temat a dana czesc kursu ma sens gdy sie przeczyta calosc od poczatku do konca i wtedy dopiero zacznie zadawac pytania.

    Czesc 3 zakonczona - nie zrobilismy przykladow, nie zrobilismy formatow do raportow tekstowych, nie tknelismy i nie tkniemy nawet logow apacza...

    Zycze milego weekendu

    EDIT: skasowane posty przywrocilem aby inni mogli zobaczyc...
    Ostatnio edytowane przez TQM : 05-03-2008 - 15:52
    ctrl-alt-del.cc - soft reset site for IT admins and other staff :-)

  7. #7
    Avatar Nikow
    Nikow jest offline -=[ZRP]=-
    Zarejestrowany
    Sep 2007
    Skąd
    Różne zakątki sieci.
    Postów
    995

    Domyślnie

    Cytat Napisał TQM Zobacz post
    Czesc 3 zakonczona - nie zrobilismy przykladow, nie zrobilismy formatow do raportow tekstowych, nie tknelismy i nie tkniemy nawet logow apacza...
    To za kare? Prawda?
    http://nikowek.blogspot.com/
    Zbrojne Ramię Pingwina!
    -----BEGIN GEEK CODE BLOCK-----
    Version: 3.12
    GCS d- s++:++ a--- C+++ UL+++ P L+++ E--- W++ N++ o K- w--
    O M- V- PS PE Y PGP++ t+ 5 X+ R tv- b++ DI- D-
    G+ e- h! r% y?
    ------END GEEK CODE BLOCK------

  8. #8
    Zarejestrowany
    Jun 2006
    Skąd
    rand(.eu)
    Postów
    8,748

    Domyślnie

    Wiesz... po prostu nie lubie jak ktos nie szanuje tego co robie, zwlaszcza gdy na prawde nie mam czasu na pisanie kursu teraz, mam lepsze zajecia... mimo wszystko spialem sie, wyskrobalem nieco czasu i zaczalem pisac a tu takie zagranie... to mi sie zwyczajnie odechcialo robic cokolwiek dla ludzi, skoro tego nie potrafia nawet uszanowac. Na dzisiaj mialem w planie sporo wiecej a teraz nie wiem kiedy (a w sumie 'czy') cos dalej zaczne pisac - zwyczajnie mi sie odechcialo i tyle.

    Czy za kare czy nie - tlumacz sobie jak chcesz (albo jak Ci wygodnie) ale chyba wiesz o co mi chodzi.
    ctrl-alt-del.cc - soft reset site for IT admins and other staff :-)

  9. #9
    Zarejestrowany
    Dec 2007
    Postów
    136

    Thumbs up

    Wow, gratulacje TQM! Bardzo mi sie podoba, szczerze mowiac zadziwiajace jest dla mnie to ze ci sie CHCE, naprawde jestem pod duzym wrazeniem wiedzy i zaangazowania. Pod wzgledem merytorycznym nie mnie to oceniac. Kurde chcialbym taki e-wyklad o jakims innym jezyku .

    edit: jak pisalem nie zauwazylem tego postu powyzej. zeby nie bylo ze wafluje :u.

    edit2: kiedy mozna sie spodziewac kolejnej czesci :>?
    Ostatnio edytowane przez mtbs : 05-19-2008 - 21:46

  10. #10
    Avatar GSG-9
    GSG-9 jest offline Shapeshifter
    Zarejestrowany
    Jul 2007
    Skąd
    C:\Perl\bin
    Postów
    1,578

    Domyślnie

    parser do pokemonowej rozmowy
    nie jest moze uniwersalny, ale gdyby ktos mogl poprawic... :P

    Kod:
    #!/usr/bin/perl -w
    use strict;
    my $pokemonowytekst = 'CzEsC Co U CiEbIe SlYcHaC?????? lol!111 wiEsH?';
    print "$pokemonowytekst\n";
    $pokemonowytekst =~ tr/A-Z/a-z/;   #zamieniamy wszystko na lowercase
    $pokemonowytekst =~ s/\W{2,}/. /; # zamieniamy wszystkie znaki non-word ktore nie sa pojedyncze na kropki
    $pokemonowytekst =~ s/\d{2,}/ /;   # wywalamy podwojne/potrojne/itd  znaki digit
    $pokemonowytekst =~ s/sh/sz/;       # sh/sz
    print "$pokemonowytekst\n";
    War, war never changes.

Strona 1 z 2 12 OstatniOstatni

Podobne wątki

  1. [Perl] Kurs Perl - cz.1 - wprowadzenie i podstawy
    By TQM in forum Perl/Python/TCL/Prolog
    Odpowiedzi: 22
    Autor: 10-27-2014, 00:50
  2. Odpowiedzi: 31
    Autor: 05-20-2008, 17:01
  3. Perl-echo.pl-smthg wrong?
    By Efraim in forum Perl/Python/TCL/Prolog
    Odpowiedzi: 12
    Autor: 11-14-2007, 17:03
  4. bot irc PERL
    By jaszu in forum Perl/Python/TCL/Prolog
    Odpowiedzi: 1
    Autor: 08-01-2007, 08:40
  5. Problem z Petla Perl
    By szpuni in forum Perl/Python/TCL/Prolog
    Odpowiedzi: 11
    Autor: 07-03-2006, 15:23

Zasady Postowania

  • Nie możesz zakładać nowych tematów
  • Nie możesz pisać wiadomości
  • Nie możesz dodawać załączników
  • Nie możesz edytować swoich postów
  •  
Subskrybuj