Karakterlánc (string)

Speciális karakterek

Néhány hasznos (és kevésbe hasznos) speciális karakter:

In [ ]:
uj_sor = "\n"           # 
horizontalis_tab = "\t" # vizszintes tabulator
rep = "\\"              # forditott per
egyes_idezojel = "\'"   # '
kettes_idezojel = "\""  # "
############################# a regi teletype-okon meg hasznos volt
sipolo_karakter = "\a"  # csengo (mar nem minden verzio tamogatja)
kocsi_vissza = "\r"     # a sor elejere ugrik, de nem emel sort
vertikalis_tab = "\v"   # 

Egy példa a \n és \t használatára:

In [1]:
print "Tablazat:\n\n  Honnan\tHova\n-------------------------\n  innen \toda"
Tablazat:

  Honnan	Hova
-------------------------
  innen 	oda

Egyszerű string műveletek

Részsztring:

In [2]:
s = "Elsomasodikharmadik"
print s[:4]
print s[4:11]
print s[11:]
Elso
masodik
harmadik

Összefűzés (karakterláncot csak karakterlánccal lehet összeadni):

In [3]:
s = "kiskutya"
print "5 " + s
5 kiskutya
In [4]:
print 5 + s
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-134562b9452d> in <module>()
----> 1 print 5 + s

TypeError: unsupported operand type(s) for +: 'int' and 'str'
In [5]:
s = "kiskutya"
mennyiseg = 5
print str(mennyiseg) + " " + s
5 kiskutya

Tehát az str függvénnyel tudunk változókat stringgé alakítani.

Hasznos string metódusok

Kis- és nagybetűk

In [6]:
s = "hol KIS-, hol NAGYbetuk"

Az első szó kezdődjön nagybetűvel, az összes többi betű legyen kicsi:

In [7]:
s.capitalize()
Out[7]:
'Hol kis-, hol nagybetuk'

Csupa nagybetűssé tevés:

In [8]:
s.upper()
Out[8]:
'HOL KIS-, HOL NAGYBETUK'

Csupa kisbetűssé tevés:

In [9]:
s.lower()
Out[9]:
'hol kis-, hol nagybetuk'

Csak az ábécé betűit tartalmazza-e (emlékeztető: a szóköz nem az ábécé betűje):

In [10]:
s.isalpha()
Out[10]:
False

Részlánc (részsztring) és részekre vágás: split

Ha egy részsztring pontos helyét is tudni akarjuk:

In [11]:
'betu' in s
Out[11]:
True
In [12]:
s.find('betu')
Out[12]:
18

Karakterlánc felbontása megadott szeparátor karakter segítségével (ha a szeparátor nincs megadva, nem látható karaktereknél vág szét). Eredményül visszakapjuk a részsztringek listáját:

In [13]:
s.split()   # szokozokkel szavakra vagjuk
Out[13]:
['hol', 'KIS-,', 'hol', 'NAGYbetuk']
In [14]:
s = "elso masodik\tharmadik\nnegyedik"
s.split()
Out[14]:
['elso', 'masodik', 'harmadik', 'negyedik']
In [15]:
s = "elso, masodik, harmadik, negyedik"
s.split(", ")            # itt egy vesszo es egy szokoz is van!
Out[15]:
['elso', 'masodik', 'harmadik', 'negyedik']

Törlés a szélekről: strip

Nem látható (whitespace) karakterek törlése a karakterlánc elejéről és végéről, vagy megadott karakterek törlése az elejéről és végéről:

In [16]:
s = '  \t szokozok \t \n\n    '
s.strip()
Out[16]:
'szokozok'
In [17]:
s = "...vesszovel kezdodik es ponttal vegzodik vagy forditva,"
print s.strip(".,")   # mindket vegerol
print s.rstrip(".,")  # csak jobbrol torol
print s.lstrip(".,")  # csak balrol torol
vesszovel kezdodik es ponttal vegzodik vagy forditva
...vesszovel kezdodik es ponttal vegzodik vagy forditva
vesszovel kezdodik es ponttal vegzodik vagy forditva,

Formázás

Igazítás

In [18]:
s = "hol vagyok"
In [19]:
print '0123456789'*3
print s.center(30)
print s.rjust(30)
print s.ljust(30)
012345678901234567890123456789
          hol vagyok          
                    hol vagyok
hol vagyok                    

A paraméterként átadott érték szabályozza a létrejött string hosszát.

Így egy táblázat (tömb) kiírása jobban kezelhető:

In [20]:
tablazat = [["Elso sor", -2, -310], ["Masodik sor", 3, 1], ["Harmadik sor",-321, 11]]
karakteres_tablazat = ""
for sor in tablazat:
    karakteres_tablazat += sor[0].ljust(13)
    for i in range(1, len(sor)):
        karakteres_tablazat += str(sor[i]).rjust(7)
    karakteres_tablazat += "\n" 
print karakteres_tablazat
Elso sor          -2   -310
Masodik sor        3      1
Harmadik sor    -321     11

Formázás a format metódussal

Itt az objektum a formátumot leíró karakterlánc és a format metódus argumentumai a behelyettesítendő értékek. A formátumban { és } között először a format argumentumának indexe szerepel, majd opcionálisan : után a formátum leírása:

In [21]:
'{0}-{1}-{2} {0}, {1}, {2}, {0}{0}{0}'.format('X', 'Y', 'Z')
Out[21]:
'X-Y-Z X, Y, Z, XXX'
Jel Jelentés
d Decimális (ezt kell tudni)
b Bináris
o Oktális
x, X hex, HEX formátum
f, F (float) lebegőpontos szám
e, E (exp) lebegőpontos szám exponenciális alakban
< balra igazít
> jobbra igazít
^ középre igazít
c^ középre igazít és körülötte az opcionális 'c' karakterrel kitölt
In [22]:
print "01234 01234 01234 0123456789"
print '{0:5} {1:5d} {2:>5} {3:*^10}'.format('0123', 1234, '|', 'kozepe')
01234 01234 01234 0123456789
0123   1234     | **kozepe**
In [23]:
"int {0:d},  hex {0:x} {0:X},  oct {0:o},  bin {0:b}".format(42)
Out[23]:
'int 42,  hex 2a 2A,  oct 52,  bin 101010'
In [24]:
"{0}, {0:e}, {0:f}, {0:8.4}, {0:15.1f}".format(-12.345)
Out[24]:
'-12.345, -1.234500e+01, -12.345000,   -12.35,           -12.3'
In [25]:
'A kozeppont: ({x}, {y})'.format(x=3, y=5)
Out[25]:
'A kozeppont: (3, 5)'
In [26]:
x1 = 3; y1 = 4
print 'A kozeppont: ({x}, {y})'.format(x=x1, y=y1)
A kozeppont: (3, 4)
In [27]:
formazott_tablazat = ""
for sor in tablazat:
    formazott_tablazat += "{0:13}".format(sor[0])
    for i in range(1, len(sor)):
        formazott_tablazat += "{0:7d}".format(sor[i])
    formazott_tablazat += "\n" 
print formazott_tablazat
Elso sor          -2   -310
Masodik sor        3      1
Harmadik sor    -321     11

Reguláris kifejezések

Adott jellemzőkkel rendelkező karakterláncok felismerése a cél (pl. érvényes email-cím, dátum, római szám, IP-cím,...)

Olvasnivalók:

Vannak online tesztoldalak, ahol programozás nélkül lehet próbálgatni a reguláris kifejezéseket. Ezek egyike a regex101.com.

Építőelemek:

A reguláris kifejezésekben használt metakarakterek: . ^ $ * + ? { } [ ] ( ) \ |

Jel Neve Jelentése (mire illeszkedik)
. pont bármely karakterre illeszkedik, kivéve az új sor karaktert
^ kalap a minta elejére illeszkedik
$ dollár a minta végére illeszkedik
| pipa logikai vagy a környező RE-ekre
[] szögletes zárójel karakter osztály, a szögletes zárójelek közötti karakterek valamelyikeire bármilyen sorrendben illeszkedik
[^ab@] tagadás bármi, kivéve a, b vagy @
[0-6] tartomány 0 és 6 közötti számokra illeszkedik
[a-fA-F] tartomány ASCII kis és nagy betűkre illeszkedik a-tól f-ig
() kerek zárójel hivatkozható csoportosítás
* csillag a megelőző RE 0 vagy többszöri ismétlése
+ plusz a megelőző RE 1 vagy többszöri ismétlése
? kérdőjel az előző RE 0 vagy egyszeri ismétlése
{3} kapcsos a mintában pontosan három karakter lehet
{3,} kapcsos a mintában legalább három vagy több karakter lehet
{,3} intervallum a mintában legfeljebb három karakter lehet
{1,4} intervallum a mintában legalább egy, legfeljebb négy karakter lehet
\ rep a spec. karakterek escape-elésére
Általános karakterosztályok
\d decimális szám
\D nem decimális szám, minden más
\s szóköz karakter
\S bármely más karakter a szóközön kívül
\w bármely szókarakter: alfanumerikus karakter vagy aláhúzás
\W bármi, ami nem szókarakter (nem alfanumerikus és nem aláhúzás)
\b szóhatár

Példák

  1. Néggyel osztható 2-jegyű számok: [02468][048]|[13579][26]
  2. '-jelek vagy "-jelek közé zárt szöveg: (['"])[^\1]*\1
  3. Bármely lebegőpontos szám: ^[+-]?(\d+(\.\d+)?|\.\d+)([eE][+-]?\d+)?$
  4. Nagy betűkkel írt római számok: M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})

Feladatok:

  1. Hexadecimális színkód: 3 darab hexadecimális szám egymás után pl: A34DC8
  2. Évszám yyyy-mm-dd formátumban

Reguláris kifejezések pythonban

Először be kell töltenünk a re csomagot, mely tartalmazza a python regexp függvényeit:

In [28]:
import re

Majd a findall függvénnyel megkereshetjük egy karakterláncban az összes részláncot, mely illeszkedik egy megadott reguláris kifejezésre:

In [29]:
pattern = r'[0-9]+\s[a-z]+'
string = r"volt egyszer 25 kiskutya, elmentek 13 varosba"
print re.findall(pattern, string)
['25 kiskutya', '13 varosba']

A karakterláncokban az eszképelt, azaz a \ jellel kezdődő karakterek (\n, \t, \) és a reguláris kifejezések \ jellel kezdődő parancsaiból adódó bizonytalanságok elkerülésére helyesebb, ha a reguláris kifejezések karakterláncait nyers (raw) formában adjuk meg, vagy minden karaktert eszképeljünk. Nyers formában tehát a \ repjelet jelent! Nyers karakterláncot az elé írt r betűvel jelöljük. A fenti példa működne nem nyersen is, mert a \s nem eszkép karakter:

In [30]:
nyers = r"aa\txx\s"
nem_nyers = "aa\txx\s"
eszkepelt = "aa\txx\\s"
print "Nyers:     " + nyers
print "Nem nyers: " + nem_nyers
print "Eszkepelt: " + eszkepelt
Nyers:     aa\txx\s
Nem nyers: aa	xx\s
Eszkepelt: aa	xx\s

Nézzük még meg hogyan tudunk lecserélni megtalált részeket stringekben:

In [31]:
mit = r'[0-9]+\s[a-z]+'
mire = r'12 majom'
miben = "volt egyszer 25 kiskutya, elmentek 13 varosba"
print re.sub(mit, mire, miben)
volt egyszer 12 majom, elmentek 12 majom

Most \1-el hivatkozunk a () zárójelek közt megtalált részre:

In [32]:
mit = r'[0-9]+\s([a-z]+)'
mire = r'12 \1'
miben = "volt egyszer 25 kiskutya, elmentek 13 varosba"
print re.sub(mit, mire, miben)
volt egyszer 12 kiskutya, elmentek 12 varosba

Több dologra is lehet hivatkozni: \2, \3,...

In [33]:
mit = r'([0-9]+)\s([a-z]+)'
mire = r'talan \1 \2'
miben = "volt egyszer 25 kiskutya, elmentek 13 varosba"
print re.sub(mit, mire, miben)
volt egyszer talan 25 kiskutya, elmentek talan 13 varosba
In [ ]: