DJFZ-2023/lab-02/lab-02.ipynb
Michał Zaręba b49e17d9bd small fix
2023-10-27 23:48:24 +02:00

641 lines
16 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"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"
}
],
"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
}