From 8eeebffd6798f6321eb783923b694e145f7cb0b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Zar=C4=99ba?= Date: Fri, 27 Oct 2023 23:47:25 +0200 Subject: [PATCH] Dodanie lab02 --- lab-02/lab-02.ipynb | 650 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 650 insertions(+) create mode 100644 lab-02/lab-02.ipynb diff --git a/lab-02/lab-02.ipynb b/lab-02/lab-02.ipynb new file mode 100644 index 0000000..7e1a405 --- /dev/null +++ b/lab-02/lab-02.ipynb @@ -0,0 +1,650 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Języki formalne i złożoność obliczeniowa\n", + "## Część 1: Wprowadzenie do biblioteki re\n" + ], + "metadata": { + "collapsed": false + }, + "id": "f5376d249e31d5aa" + }, + { + "cell_type": "markdown", + "source": [ + "Wyrażenia regularne będziemy robić na podstawie języka python3. Dokumentacja: https://docs.python.org/3.11/library/re.html\n", + "\n", + "Użyteczna strona do testowania wyrażeń regularnych: https://regex101.com/\n" + ], + "metadata": { + "collapsed": false + }, + "id": "ce091d4ec144df32" + }, + { + "cell_type": "markdown", + "source": [ + "# Podstawowe funkcje" + ], + "metadata": { + "collapsed": false + }, + "id": "35428280eb1f704" + }, + { + "cell_type": "markdown", + "source": [ + "## Match\n", + "match - zwraca dopasowanie od początku stringa" + ], + "metadata": { + "collapsed": false + }, + "id": "9674be284007455d" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "import re\n", + "wynik = re.match(r'Ala', 'Ala ma kota. Kot ma Alę.')\n", + "print(wynik)\n", + "print(f\"Dopasowano: '{wynik.group()}', początek: {wynik.start()}, koniec: {wynik.end()}\")\n" + ], + "metadata": { + "collapsed": false + }, + "id": "fa7637b60ae679b5" + }, + { + "cell_type": "markdown", + "source": [ + "## Search\n", + "search - zwraca pierwsze dopasowanie w napisie\n" + ], + "metadata": { + "collapsed": false + }, + "id": "626c591ab52a086" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "# search\n", + "wynik = re.search(r'ni', 'Może nie najtaniej, ale jako tako.')\n", + "\n", + "if wynik:\n", + " print(f\"Dopasowano: '{wynik.group()}', początek: {wynik.start()}, koniec: {wynik.end()}\")\n", + "else:\n", + " print('Nie znaleziono szukanego ciągu znaków.')" + ], + "metadata": { + "collapsed": false + }, + "id": "4f5d7077a85b7108" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "tekst = \"Kto zakłóca ciszę nocną musi ponieść karę: 100 batów!\"\n", + "\n", + "wzorzec = re.compile('ci')\n", + "\n", + "wynik = wzorzec.search(tekst)\n", + "\n", + "if wynik:\n", + " print(f\"Dopasowano: '{wynik.group()}', początek: {wynik.start()}, koniec: {wynik.end()}\")\n", + "else:\n", + " print('Nie znaleziono szukanego ciągu znaków.')" + ], + "metadata": { + "collapsed": false + }, + "id": "b9da286f8d6936fb" + }, + { + "cell_type": "markdown", + "source": [ + "## findall\n", + "findall - zwraca listę wszystkich dopasowań\n" + ], + "metadata": { + "collapsed": false + }, + "id": "600b87dd6af48c04" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "# findall\n", + "wzorzec = re.compile('o')\n", + "\n", + "wynik = wzorzec.findall(tekst)\n", + "\n", + "if len(wynik) > 0:\n", + " print(type(wynik))\n", + " print(f'Dopasowano: {wynik}')\n", + "else:\n", + " print(f'{wynik} Nie znaleziono szukanego ciągu znaków.')" + ], + "metadata": { + "collapsed": false + }, + "id": "37a93d9d61c6178d" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "wzorzec = re.compile('o')\n", + "\n", + "wynik = wzorzec.finditer(tekst)\n", + "for w in wynik:\n", + " print(type(w))\n", + " print(f'Dopasowano: \"{w.group()}\", początek: {w.start()}, koniec: {w.end()}')" + ], + "metadata": { + "collapsed": false + }, + "id": "3232906632de2fe1" + }, + { + "cell_type": "markdown", + "source": [ + "*Uwaga*: pobierając z iteratora elementy, usuwamy je, nie można zatem ponownie się do nich odwołać." + ], + "metadata": { + "collapsed": false + }, + "id": "62e8a0370ee58827" + }, + { + "cell_type": "markdown", + "source": [ + "## Użycie przedrostka 'r' w wyrażeniach regularnych w Pythonie\n", + "\n", + "W Pythonie przedrostek `r` przed łańcuchem znaków oznacza \"surowy\" łańcuch znaków (ang. *raw string*). Dlaczego jest to przydatne w kontekście wyrażeń regularnych?\n", + "\n", + "Wyrażenia regularne często używają znaków specjalnych, takich jak `\\d`, `\\w`, `\\b` itp. W standardowych łańcuchach znaków w Pythonie, znaki te mają specjalne znaczenie. Na przykład, `\\t` oznacza tabulację, a `\\n` oznacza nową linię.\n", + "\n", + "Jeśli chcemy użyć takiego wyrażenia regularnego w Pythonie, musielibyśmy podwajać znaki ukośnika, aby uniknąć konfliktu z wbudowanymi sekwencjami ucieczki w łańcuchach znaków, np. `\\\\d`, `\\\\w`." + ], + "metadata": { + "collapsed": false + }, + "id": "6342ff85cd5fc35a" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "# Bez użycia surowego łańcucha znaków\n", + "result1 = re.findall(\"\\\\d+\", \"123 abc 456\")\n", + "print(result1)\n", + "\n", + "# Używając surowego łańcucha znaków\n", + "result2 = re.findall(r\"\\d+\", \"123 abc 456\")\n", + "print(result2)\n" + ], + "metadata": { + "collapsed": false + }, + "id": "b09fa3103ec18719" + }, + { + "cell_type": "markdown", + "source": [ + "## sub\n", + "Kolejną użyteczną metodą jest sub(), która pozwala na zmianę wzorca na inny ciąg znaków:" + ], + "metadata": { + "collapsed": false + }, + "id": "e9e3f41e90bbd746" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "wzorzec = re.compile(r'ni')\n", + "\n", + "zmieniony = wzorzec.sub('Ni!', tekst)\n", + "print(zmieniony)" + ], + "metadata": { + "collapsed": false + }, + "id": "af633211d7faca67" + }, + { + "cell_type": "markdown", + "source": [ + "## split\n", + "split - dzieli napis na podstawie wzorca" + ], + "metadata": { + "collapsed": false + }, + "id": "ea9205aa03ed7476" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "wzorzec = re.compile(r' ')\n", + "\n", + "wynik = wzorzec.split(tekst)\n", + "print(f'Uzyskano {len(wynik)} wyniki/ów.')\n", + "for w in wynik:\n", + " print(w)" + ], + "metadata": { + "collapsed": false + }, + "id": "71dc3b254a93f31c" + }, + { + "cell_type": "markdown", + "source": [ + "# Metaznaki\n", + "[] - zbiór znaków\n", + "\n", + ". - jakikolwiek znak\n", + "\n", + "^ - początek napisu\n", + "\n", + "$ - koniec napisu\n", + "\n", + "? - znak występuje lub nie występuje\n", + "\n", + "\\* - zero albo więcej pojawień się\n", + "\n", + "\\+ - jeden albo więcej pojawień się\n", + "\n", + "{} - dokładnie tyle pojawień się\n", + "\n", + "| - lub\n", + "\n", + "() - grupa\n", + "\n", + "\\ - znak ucieczki\n", + "\n", + "\\d digit\n", + "\n", + "\\D nie digit\n", + "\n", + "\\s whitespace\n", + "\n", + "\\S niewhitespace" + ], + "metadata": { + "collapsed": false + }, + "id": "4b16abb6848f09ae" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "wzorzec = re.compile(r'.')\n", + "print(wzorzec.findall(tekst))" + ], + "metadata": { + "collapsed": false + }, + "id": "ac6669cac4f52d27" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "# jeden lub wiecej / zero lub wiecej\n", + "\n", + "tekst = \"BCAAABGTAABBBCCTTSAGG4324242\"\n", + "print(f'Łańcuch: {tekst}')\n", + "wzorzec = re.compile(r'X+')\n", + "print(f'Jeden lub więcej X: {wzorzec.findall(tekst)}')\n", + "wzorzec = re.compile(r'X*')\n", + "print(f'Zero lub więcej X: {wzorzec.findall(tekst)}')" + ], + "metadata": { + "collapsed": false + }, + "id": "634e4b66a5081f97" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "# zero lub jeden\n", + "\n", + "print(f'Łańcuch: {tekst}')\n", + "wzorzec = re.compile(r'.?')\n", + "print(wzorzec.findall(tekst))\n", + "wzorzec = re.compile(r'.?T')\n", + "print(wzorzec.findall(tekst))" + ], + "metadata": { + "collapsed": false + }, + "id": "44195e00a81b23fb" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "print(f'Łańcuch: {tekst}')\n", + "wzorzec = re.compile(r'A+')\n", + "print(f'Dopasowanie zachłanne: {wzorzec.findall(tekst)}')\n", + "wzorzec = re.compile(r'A+?')\n", + "print(f'Dopasowanie leniwe: {wzorzec.findall(tekst)}')" + ], + "metadata": { + "collapsed": false + }, + "id": "ea861a33e942d42a" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "print(f'Łańcuch: {tekst}')\n", + "\n", + "# dokladnie 3 dopasowania\n", + "wzorzec = re.compile(r'A{3}')\n", + "print(f'{wzorzec.findall(tekst)}')\n", + "\n", + "# pomiedzy 2 i 3 dopasowania\n", + "wzorzec = re.compile(r'A{2,3}')\n", + "print(f'{wzorzec.findall(tekst)}')\n", + "\n", + "# 2 lub wiecej dopasowan\n", + "wzorzec = re.compile(r'A{2,}')\n", + "print(f'{wzorzec.findall(tekst)}')\n", + "\n", + "# 3 lub mniej dopasowan\n", + "wzorzec = re.compile(r'A{,3}')\n", + "print(f'{wzorzec.findall(tekst)}')" + ], + "metadata": { + "collapsed": false + }, + "id": "751272b81731af36" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "# poczatek lub koniec lancucha\n", + "\n", + "tekst = \"Ale pięknie pachnie! Maciek, co gotujesz?\"\n", + "\n", + "# poczatek lancucha\n", + "wzorzec = re.compile(r'^Ale')\n", + "print(f'{wzorzec.findall(tekst)}')\n", + "\n", + "# poczatek lancucha\n", + "wzorzec = re.compile(r'^ale')\n", + "print(f'{wzorzec.findall(tekst)}')\n", + "\n", + "# koniec lancucha\n", + "wzorzec = re.compile(r'Ale$')\n", + "print(f'{wzorzec.findall(tekst)}')\n", + "\n", + "# koniec lancucha + znak ucieczki\n", + "wzorzec = re.compile(r'gotujesz\\?$')\n", + "print(f'{wzorzec.findall(tekst)}')" + ], + "metadata": { + "collapsed": false + }, + "id": "97bcd3ff7cc3913" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "# grupy znakow\n", + "wzorzec = re.compile(r'[A-Z]')\n", + "print(f'Duże litery: {wzorzec.findall(tekst)}')\n", + "\n", + "wzorzec = re.compile(r'[a-z]')\n", + "print(f'Małe litery: {wzorzec.findall(tekst)}')\n", + "\n", + "wzorzec = re.compile(r'[A-z]')\n", + "print(f'Małe i duże litery: {wzorzec.findall(tekst)}')\n", + "\n", + "wzorzec = re.compile(r'[aeiou]')\n", + "print(f'Samogłoski: {wzorzec.findall(tekst)}')" + ], + "metadata": { + "collapsed": false + }, + "id": "ee099e6e1e5e2f80" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "# wzorzec(?=X) - dopasowanie, jeśli po nim występuje X\n", + "\n", + "tekst = \"ACABADAHSAIIIQIIINSAODIANSAAGAGAGGGGPAAG\"\n", + "\n", + "print(f'Łańcuch: {tekst}')\n", + "wzorzec = re.compile(r'G+(?=A)')\n", + "print(f'{wzorzec.findall(tekst)}')" + ], + "metadata": { + "collapsed": false + }, + "id": "dd6351952639ef42" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "tekst = \"Ale się zrobiła świąteczna atmosfera.\"\n", + "wzorzec = re.compile(r'Ale|świąteczna|zrobiła')\n", + "print(f'{wzorzec.findall(tekst)}')" + ], + "metadata": { + "collapsed": false + }, + "id": "c7f3e1b9d16c91db" + }, + { + "cell_type": "markdown", + "source": [ + "## Znaki specjalne\n", + "\n", + "\\s\t- biały znak\n", + "\n", + "\\S\t- nie-biały znak\n", + "\n", + "\\d\t- cyfra\n", + "\n", + "\\D\t- nie-cyfra\n", + "\n", + "\\w\t- znaki alfanumeryczne (litery i cyfry) oraz\n", + " \n", + "\\W\t- znaki nie-alfanumeryczne i nie\n", + " \n", + "\\b\t- początek lub koniec ,,słowa’’\n", + " \n", + "\\B\t- nie początek lub koniec ,,słowa''\n", + "\n", + "[a-z]\t- małe litery\n", + "\n", + "[A-Z]\t- wielkie litery\n", + "\n", + "[0-9]\t- cyfry\n" + ], + "metadata": { + "collapsed": false + }, + "id": "c1a7435b7887f5c2" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "wzorzec = re.compile(r'\\w+')\n", + "print(f'Wyrazy: {wzorzec.findall(tekst)}')\n" + ], + "metadata": { + "collapsed": false + }, + "id": "3b1b1f147233455d" + }, + { + "cell_type": "markdown", + "source": [ + "## Część II: Zadania praktyczne\n", + "\n", + "### Zadanie 1: Wyszukiwanie numerów telefonu\n", + "\n", + "Napisz wyrażenie regularne, które znajdzie wszystkie numery telefonu w tekście. Zakładamy, że numer telefonu ma format `xxx-xxx-xxx` lub `xxx xxx xxx`.\n" + ], + "metadata": { + "collapsed": false + }, + "id": "e0670d19927add2b" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "tekst = \"\"\"\n", + "Jan: 123-456-789\n", + "Anna: 987 654 321\n", + "Karol: 456-789-123\n", + "Zbyszek: 53252525342252\n", + "Tytus: aaaa666432\n", + "\"\"\"\n", + "\n", + "wzorzec = re.compile(r\"\")\n", + "print(f'Numery: {wzorzec.findall(tekst)}')" + ], + "metadata": { + "collapsed": false + }, + "id": "aecbbf61477429ac" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "tekst = \"\"\"\n", + "jan.kowalski@gmail.com\n", + "anna.zielinska@amu.edu.pl\n", + "karol.nowak@interia.pl\n", + "hello world\n", + "@test.pl\n", + "x@x\n", + "fff22@gmail.com\n", + "\"\"\"\n", + "\n", + "wzorzec = re.compile(r\"\")\n", + "print(f'Adresy: {wzorzec.findall(tekst)}')" + ], + "metadata": { + "collapsed": false + }, + "id": "1dcf9585d7b78073" + }, + { + "cell_type": "markdown", + "source": [ + "# Część III Zadanie domowe\n", + "\n", + "## Zadanie 1: Wyszukiwanie kodów pocztowych (2 pkt)\n", + "Napisz wyrażenie regularne, które znajdzie wszystkie polskie kody pocztowe w tekście. Zakładamy, że kod pocztowy ma format XX-XXX, gdzie X to cyfra.\n", + "\n", + "## Zadanie 2: Weryfikacja adresu URL (2 pkt)\n", + "Zaimplementuj wyrażenie regularne, które sprawdzi, czy dany ciąg jest poprawnym adresem URL. Zakładamy, że adres URL zaczyna się od http:// lub https://, po którym następuje nazwa domeny i opcjonalnie ścieżka.\n", + "\n", + "## Zadanie 3: Weryfikacja numeru PESEL (2 pkt)\n", + "Napisz wyrażenie regularne, które sprawdzi, czy dany ciąg jest poprawnym numerem PESEL. PESEL składa się z 11 cyfr.\n", + "\n", + "## Zadanie 4: Wyszukiwanie tagów HTML (3 pkt)\n", + "Zaimplementuj wyrażenie regularne, które znajdzie wszystkie tagi (otwierające i zamykające) w tekście HTML.\n", + "\n", + "## Zadanie 5: Weryfikacja hasła (4 pkt)\n", + "Napisz wyrażenie regularne, które sprawdzi, czy dane hasło spełnia następujące kryteria:\n", + "\n", + "Ma co najmniej 8 znaków.\n", + "\n", + "Zawiera co najmniej jedną dużą literę.\n", + "\n", + "Zawiera co najmniej jedną małą literę.\n", + "\n", + "Zawiera co najmniej jedną cyfrę.\n", + "\n", + "Zawiera co najmniej jeden ze znaków specjalnych: @, #, $, %, &, *, !.\n", + "\n", + "\n", + "Rozwiązania zadań należy wysłać na adres email: **miczar1@amu.edu.pl** z tytułem: **[DJFZ][NrIndeksu] Zadanie domowe Zajęcia 2**. Jako załącznik należy wysłać 5 plików .py (zadanie1.py, zadanie2.py itd.) z rozwiązaniem. Skrpyty na wejściu mają przyjmować plik tekstowy `in.txt` a następnie zapisać rezultaty do pliku `out.txt` (każdy pasujący element to jeden wiersz) lub (True/False jak w poprzednim zadaniu) Przykładowe wywołanie skryptu: `python zadanie1.py in.txt`." + ], + "metadata": { + "collapsed": false + }, + "id": "ae6ffce379f9676d" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [], + "metadata": { + "collapsed": false + }, + "id": "c50e32432390f9eb" + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}