Jump to content
  • Search In
    • More options...
    Find results that contain...
    Find results in...

    Wyrażenia regularne w AMXX i moduł Regex


    Recommended Posts

    • Cała zawartość 5
    • Temat został założony
    • Ostatnia odpowiedź

    Top Posters In This Topic

    Najpopularniejsze posty

    Siema. Zbliżają się święta to z tej okazji machnę jakiś poradnik Jest to poradnik dla skrypterów AMXX, więc czytając go powinieneś znać podstawy scriptingu AMXX (zwłaszcza obsługę stringów) oraz pod

    Posted Images

    Siema. Zbliżają się święta to z tej okazji machnę jakiś poradnik :D

    Jest to poradnik dla skrypterów AMXX, więc czytając go powinieneś znać podstawy scriptingu AMXX (zwłaszcza obsługę stringów) oraz podstawowe mechanizmy stosowane w programowaniu/skryptach (tablice, pętle, instrukcje warunkowe/wyboru itp.)

     

     

    I. Wyrażenia regularne.

    Pisząc skrypty/programy prędzej czy później zachodzi potrzeba aby sprawdzić czy dany ciąg znaków , obojętnie czy jakiś przetwarzany w pamięci czy widoczny dla użytkownika/gracza należy do pewnej grupy ciągu znaków. Zwłaszcza przy pracy z bazami danych lub przy sprawdzaniu poprawności wpisywanych danych do formularza. Tutaj przychodzą nam z pomocą wyrażenia regularne. Wytłumaczę po krótce co to jest , dla bardziej zainteresowanych odsyłam do lektury -> WIKI

    Wyrażenie regularne jest to ciąg znaków o dowolnej długości który może zostać wygenerowany wg. pewnego stałego wzorca. Używa się ich do sprawdzenia czy dany ciąg znaków pasuje do wzorca i należy do pewnej grupy stringów. Przykładowymi wartościami z życia które możemy wygenerować za pomocą wyrażeń regularnych są np. kod pocztowy, adres e-mail, adres strony. Wyrażeniami regularnymi nie będą jednak imię czy ulica , ponieważ nie jesteśmy w stanie określić wzorca dla nich.

    Przyjrzyjmy się np. adresowi e-mail. Każdy adres wygląda podobnie , składa się z takich samych części np. admin@cskatowice.com

     

    Składa się z kolejnych części : (części oddziele kreskami)

     

    Nazwa Własna | Małpa(@) | Nazwa domeny | Kropka | Końcówka domeny

     

    Czy jesteśmy w stanie wygenerować taki ciąg znaków ? Tak. Wygląda mniej więcej tak : <dowolne_znaki>@<dowolne_znaki>.<dowolne_litery (max 3)>

    Teraz możemy sobie zadać pytanie np. czy napis cskatowice jest email'em ? My wiemy o tym że nie, jednak żeby komputer też o tym wiedział musimy go porównać do wzorca podanego wyżej.

    Czy mamy pierwszą część składającą się z dowolnych znaków ? TAK

    Czy po tym występuje @ ? NIE

     

    Na tym etapie kończymy analizę, ponieważ nie spełniliśmy przynajmniej jednego z etapów.

    Teraz inny napis ogen@cskatowice.com

    Czy mamy pierwszą część składającą się z dowolnych znaków ? TAK

    Czy po tym występuje @ ? TAK

    Czy po tym występuje ciąg dowolnych znaków ? TAK

    Czy po tym występuje kropka ? TAK

    Czy po kropce występuje ciąg liter o maksymalnej długości 3 ? TAK

    To jest email :)

     

     

    II. Symbole i generowanie wzorca.

    Obsługa wyrażeń regularnych w AMXX jest wzorowana na tej z innych języków jak PHP, więc nasz standard symboli będzie zgodny z tym z PHP.

     

    regex.png

     

    Przykłady wzorców i napisy należące do nich :

    \d{1,3} - interpretacja: \d - liczby, {1,3} - od jednej do trzech ; akceptuje wszystkie liczby 1,2,3 cyfrowe np. 234 , 54 , 67 , 37 , 2

    \w*\d+.* - interpretacja: \w* - litery(opcjonalnie), \d+ - liczby(obowiązkowo), .* - dowolny znak(opcjonalnie); akceptuje np. ab2 , vgd562x , czd23, 245 , 9 , 9273szc

    (x|y)\w{2,4}(x|y) - interpretacja: (x|y) - a lub b, \w{2,4} - od 2 do 4 liter, (x|y - x lub y; akceptuje słowa kończące się i zaczynające na x lub y od 4 do 6 liter np. xvdfy , xbgcy, xxxxx, yyyy, xshpy

     

    Jak będzie wyglądać wzorzec dla email'a ?

    .+@.+\.\w{2,3} - intepretacja: .+ - przynajmniej jeden dowolny znak, @ - małpa (jako znak), .+ - przynajmniej jeden dowolny znak, \. - kropka (jako znak), \w{3} - 3 literowy ciąg znaków; akceptuje słowa :

    admin@cskatowice.com, cskatowice@cskatowice.com , admin123@cskatowice321.pl

     

     

    III. Implementacja w AMXX

    Teraz omówię jak użyć tego w AMXX. Jeden z modułów AMXX - "Regex" zaimportowany z innych języków umożliwia nam obsługę wyrażeń. Na początku dołączamy go do naszego kodu :

    #include <regex>

    Kolejną rzeczą na którą warto zwrócić uwagę to fakt, że moduł ten wprowadza nam nowy typ zmiennych Regex. Jest to typ wyliczeniowy, zdefiniowany przez autorów służy do obsługi wyrażeń i zapisywania wyniku porównania wzorca z ciągiem znaków. Przyjmuje predefiniowane stałe :

     

    REGEX_OK - ciąg znaków pasuje do wzorca

    REGEX_NO_MATCH - ciąg znaków nie pasuje do wzorca

    REGEX_MATCH_FAIL - błąd porównania (do odczytania przez tablice podaną jako jeden z parametrów)

    REGEX_PATTERN_FAIL - błąd wyrażenia , wzorzec nie poprawnie zdefiniowany (przypominam że wzorzec musi być stałą wartością !)

     

    Zmienne deklarujemy w ten sposób :

    new Regex:zmienna;

    Nie próbujcie ustalać jej liczb czy liter jako wartość , ponieważ to specyficzny typ danych a tym bardziej porównywać do nich :)

     

     

    Najprzydatniejsze funkcje :

    regex_compile - przygotowuje wzorzec do wielokrotnego użytku. Przed użyciem musimy zadeklarować zmienną do której zapiszemy zwracaną wartość oraz tablice gdzie możemy ewentualnie zapisać treść błędu.

    Funkcje tego modułu zwracają wartość logiczną do zmiennej przekazywanej w parametrze oraz wartość typu Regex do zmiennej którą przypiszemy do niej. Przykład użycia :

    new returned_value, error_cskatowice[32];
    new Regex:wyr_reg = regex_compile("\w*\d+.*",returned_value, error_cskatowice, 31);

    regex_match / regex_match_c - porównuje wzorzec z ciągiem znaków podanym jako stała wartość lub tablica (regex_match_c używamy do wzorców zdefiniowanych wcześniej przez regex_compile). Przykład użycia :

    new returned_value, error_cskatowice[32];
    new Regex:wyr_reg = regex_match("abcdef123","\w*\d+.*",returned_value, error_cskatowice, 31);
    switch(wyr_reg) // rozpatrywanie wartosci wyniku Regex
    {
    	case REGEX_OK: log_amx("Dopasowano tekst do wzorca");
    	case REGEX_MATCH_FAIL: log_amx("Blad #%d",returned_value);
    	case REGEX_PATTERN_FAIL: log_amx("Blad wyrazenia: %s (#%d)", error_cskatowice, returned_value);
    	case REGEX_NO_MATCH: log_amx("Nie dopasowano tekstu do wzorca");
            // w tym wypadku nie używamy default, ponieważ to wszystkie możliwe wartości
    }
    if (returned_value>0) regex_free(wyr_reg);
    

    regex_free - "czyści" zmienną typu Regex UWAGA! należy czyścić tylko w wypadku powodzenia przy wcześniejszym porównywaniu, czyli gdy zwracana wartość logiczna jest większa od 0. Inaczej będą generowane error logi spowodowane wyciekami pamięci przy każdej próbie użycia. Przykład użycia :

    if (returned_value>0) regex_free(wyr_reg);

    Po szczegółowe opisy funkcji zapraszam do dokumentacji :

     

    IV. Dodatkowe informacje

    Budowanie bardziej złożonych wzorców dla wyrażeń regularnych może być nie co skompilowane a próbowanie każdego na sucho czasochłonne. Dlatego powstały symulatory Regex'a. Osobiście polecam ten : https://regex101.com/

    Jak wcześniej wspomniałem przy użyciu tego symulatora, będzie nas interesować standard dla PHP czyli tutaj akurat domyślny.

    Tutaj taka ciekawostka, wyrażeniami regularnymi zajmowano się już w trakcie II wojnie światowej, gdy powstawały pierwsze abstrakcyjne modele komputera działające w sposób zbliżony do dzisiejszych komputerów np. Maszyna Turinga.

    Do dzisiaj można napisać sobie (na kartce) program do takiej maszyny lub automatu skończonego, który będzie akceptował dane wyrażenia regularne :)

    Dokładne info:

    Maszyna Turinga - http://pl.wikipedia.org/wiki/Maszyna_Turinga

    Automat skończony - http://pl.wikipedia.org/wiki/Automat_sko%C5%84czony

     

     

    Poradnik napisany przez Ogen Dogen dla CSKatowice.com

    Zakaz kopiowania na inne fora bez zgody autora.

    post-224-0-02417700-1428001526_thumb.png

    Link to comment
    Share on other sites

    Guest
    This topic is now closed to further replies.
     Share

    ×
    ×
    • Create New...