automata-labs/lab-02.ipynb
2024-11-24 21:18:17 +01:00

603 lines
14 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"
}
],
"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
}