Obsługa tekstów
Klasa str, unicode i basestring
Obiekty klasy str występującej w Python 2.x
są napisami, które nie zawierają informacji na temat sposobu kodowania znaków spoza tradycyjnego zakresu ASCII. Z tego powodu, jeśli używamy klasy str,
powinniśmy zawsze pamiętać, jakie jest
kodowanie danego napisu.
Obiekt typu str otrzymujemy np. wczytując zawartość pliku
lub pobierając dokument z sieci. Nie zawsze jesteśmy w stanie jednoznacznie określić,
jakie jest kodowanie takiego dokumentu,
dlatego jeśli możliwe są w takim przypadku różne kodowania,
powinno być ono jawnie określone.
Obiekty klasy unicode
przechowują tekst w wewnętrznej reprezentacji według standardu
unicode
— kwestia kodowania traci wtedy znaczenie. Aby uzyskać obiekt unicode, np. z napisu typu str,
należy określić sposób kodowania znaków w danym napisie w momencie przekształcania go na unicode.
napis_unicode = u'Zażółć gęślą jaźń' type(napis_unicode) > unicode napis_str_utf8 = napis_unicode.encode('utf8') napis_str_utf8 > 'Za\xc5\xbc\xc3\xb3\xc5\x82\xc4\x87 g\xc4\x99\xc5\x9bl\xc4\x85 ja\xc5\xba\xc5\x84' print napis_str_utf8 # terminal ustawiony na utf8 > Zażółć gęślą jaźń print len(napis_unicode), len(napis_str_utf8) > 17 26
Ostatnia instrukcja ujawnia, że obiekt str to tak naprawdę ciąg bajtów,
traktowanych osobno — funkcja len() zwraca ich liczbę. W naszym przykładzie używamy kodowania utf8,
więc potrzeba 26 bajtów do zakodowania
powyższego napisu w tym kodowaniu.
Obiekt unicode to ciąg znaków —
len() zwraca ich liczbę.
Aby z napisu str otrzymać unicode,
używamy metody .decode() podając jako argument sposób kodowania.
# str -> decode -> unicode napis_str = 'Aj, pech! Struś dźgnął ćmę FBI! Koń lży wóz.' napis_unicode = napis_str.decode('utf8') napis_unicode > u'Aj, pech! Stru\u015b d\u017agn\u0105\u0142 \u0107m\u0119 FBI! Ko\u0144 l\u017cy w\xf3z.' # unicode -> encode -> str napis_unicode = u'Dość błazeństw, żrą mój pęk luźnych fig.' napis_str = napis_unicode.encode('windows-1250') napis_str > 'Do\x9c\xe6 b\xb3aze\xf1stw, \xbfr\xb9 m\xf3j p\xeak lu\x9fnych fig.'
Obie klasy str i unicode dziedziczą po klasie basestring. Nie da się utworzyć obiektu klasy bezpośrednio basestring
— używamy jej tylko do sprawdzania, czy jakiś obiekt jest tekstem.
isinstance(napis_str_utf8, basestring) > True isinstance(napis_unicode, basestring) > True
Formatowanie napisów
Klasy str i unicode mają bogaty zestaw
metod manipulowania tekstem.
napis = u' Ala ma kota. ' napis.strip() > u'Ala ma kota.' napis.rstrip() > u' Ala ma kota.' napis.strip().center(30) > u' Ala ma kota. ' u'abcde'.capitalize() > u'Abcde' napis.lower().islower() > True napis = napis.strip() napis.startswith('Ala') > True napis.rjust(30) > u' Ala ma kota.' napis.ljust(30) > u'Ala ma kota. ' napis.swapcase() > u'aLA MA KOTA.' napis.title() > u'Ala Ma Kota.' napis.istitle() > False napis.title().istitle() > True 'kot' in napis > True 'pies' not in napis > True napis.replace('kota', 'psa').replace('Ala', 'Adam') > u'Adam ma psa.' 'klucz: wartosc z: dwukropkiem, przecinkiem itd.'.partition(': ') > ('klucz', ': ', 'wartosc z: dwukropkiem, przecinkiem itd.') '%(miasto)s/%(miasto)s/%(ulica)s' % { 'miasto': 'Lublin', 'ulica': 'Akademicka', } > 'Lublin/Lublin/Akademicka'
Wyrażenia regularne
Wyrażenia regularne pozwalają wyszukiwać i wyodrębniać fragmenty tekstu z większej całości. Do ich konstrukcji używa się specyficznej składni. Poniższy przykład pokazuje, jak wyłuskać wszystkie adresy e-mail z zadanego tekstu.
import re regex_email = re.compile( r'''(?P<adres> (?P<login>[\w+.]+) # login, np. m.j.panczyk+umcs.pl @ # znak @ (?P<domena>\w+(\.\w+)+) # domena, np. gmail.com )''', re.IGNORECASE | re.VERBOSE ) # regex_email to obiekt skompilowanego wyrażenia regularnego tekst = u'Michał Pańczyk <moj.email@umcs.lublin.pl>, "moj_drugi_mail@domena.pl"' for match_object in regex_email.finditer(tekst): print match_object.groupdict() > {'domena': u'umcs.lublin.pl', 'login': u'moj.email', 'adres': u'moj.email@umcs.lublin.pl'} > {'domena': u'domena.pl', 'login': u'moj_drugi_mail', 'adres': u'moj_drugi_mail@domena.pl'}
Litera r przed literałem tekstowym
będącym argumentem funkcji compile()
powoduje, że znak odwrotnego ukośnika \
traci swoje znaczenie.
print r'\n' > \n
Moduł re zawiera dużo więcej przydatnych funkcji, o których można przeczytać w dokumentacji.
Przykładowe formaty serializacji danych
JSON
Do obsługi formatu JSON w Pythonie możemy użyć modułu json.
import json slownik = { 'data': 'abcdef', 'cnt': "10", 'items':[1,2,3,4], } json_str = json.dumps(slownik) json_str > '{"items": [1, 2, 3, 4], "cnt": "10", "data": "abcdef"}' json.loads(json_str) > {u'cnt': u'10', u'data': u'abcdef', u'items': [1, 2, 3, 4]}
pickle
pickle jest modułem,
który umożliwia serializację
obiektów do wewnętrznego formatu Pythona.
Podobnie, jak moduł json,
moduł pickle zawiera
m.in funkcje loads() oraz dumps().
Zamiast pickle, możesz użyć modułu
cPickle,
który jest zaimplementowany w C i działa szybciej.
YAML
Analogicznie do dwóch powyższych
formatów danych, możemy używać
YAML, przy czym moduł yaml nie jest umieszczony w standardowej bibliotece.
base64
Do obsługi base64
możemy użyć modułu
base64.
import base64 base64.encodestring('Ala ma kota') > 'QWxhIG1hIGtvdGE=\n' base64.decodestring('QWxhIG1hIGtvdGE=\n') > 'Ala ma kota'
Zadania
-
Napisz funkcję, która dostaje jako parametry napis i liczbę
width. Funkcja ma wypisać napis na standardowe wyjście w ten sposób, żeby w każdej linii było co najwyżejwidthznaków. Funkcja może dzielić słowa tylko o długości większej odwidth. -
Zmodyfikuj powyższe zadanie tak, by wypisywany tekst był wyśrodkowany (w obrębie zadanych
widthmiejsc na ekranie). -
Napisz program, który z zadanego parametrem pliku tekstowego wypisze na standardowe wyjście wszystkie poprawne adresy IP (ver. 4) — każdy w osobnej linii.
-
Napisz funkcję, która dostaje numer PESEL (napis lub liczbę) i dokonuje jego walidacji.
-
Napisz program, który dla podanego pliku tekstowego wyszukuje w nim wszystkie frazy postaci:
Anna Nowak PESEL:02271409862. Dla każdej znalezionej frazy z poprawnym numerem PESEL program ma wypisać imię, nazwisko i rok urodzenia. -
Napisz program, który dostaje jako parametry dwie nazwy plików. Pierwszy plik np.
plik.jsonma zawierać dane w formaciejson. Program ma zapisać do drugiego pliku w formaciepickleodkodowane wcześniej dane.
