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żejwidth
znakó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
width
miejsc 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.json
ma zawierać dane w formaciejson
. Program ma zapisać do drugiego pliku w formaciepickle
odkodowane wcześniej dane.