Karakterlánc (string)

Speciális karakterek

Ismétlésül néhány hasznos speciális karakter:

In [1]:
uj_sor = "\n"           #
horizontalis_tab = "\t" # vizszintes tabulator
rep = "\\"              # forditott per
egyes_idezojel = "\'"   # '
kettes_idezojel = "\""  # "

Néhány művelet:

a = "That's"
b = "fine"
Operator Description Input Output
+ Concatenation a + b That'sfine
* Repetition 2 * b finefine
[] Slice a[1] h
[:] Range Slice a[1:4] hat
in Membership 'a' in a True
not in Membership 'a' not in b True
r/R Raw String suppresses escape chars r'\n' \n
% Format: %s %d %o (octal) %x (hex) %f %e %E %g %G
In [2]:
x = 12.345
y = 12.3e10
print("f: %f, e: %e, g: %g" % (x, x, x) )
print("f: %f, e: %e, g: %g" % (y, y, y) )
f: 12.345000, e: 1.234500e+01, g: 12.345
f: 123000000000.000000, e: 1.230000e+11, g: 1.23e+11

A str() függvénnyel tudunk stringgé konvertálni.

Hasznos string metódusok

Kis- és nagybetűk

hi = "how ARE you"
Method Description Input Output
.capitalize() first letter into upper case hi.capitalize() How are you
.lower() lower case hi.lower() how are you
.upper() upper case hi.upper() HOW ARE YOU
.title() every word capitalized hi.title() How Are You
In [3]:
s = "hol KIS-, hol NAGYbetűk"

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

In [4]:
s.capitalize()
Out[4]:
'Hol kis-, hol nagybetűk'

Csupa nagybetűssé tevés:

In [5]:
s.upper()
Out[5]:
'HOL KIS-, HOL NAGYBETŰK'

Csupa kisbetűssé tevés:

In [6]:
s.lower()
Out[6]:
'hol kis-, hol nagybetűk'
Method Boolean value
.isalnum() alphanumeric characters (no symbols)?
.isalpha() alphabetic characters (no symbols)?
.islower() lower case?
.isnumeric() numeric characters?
.isspace() whitespace characters?
.istitle() is in title case?
.isupper() upper case?

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

In [7]:
"a b".isalpha()
Out[7]:
False
In [8]:
alnum = "23 apples"
num = "-1234"
title = "Big Apple"
print(alnum.isalnum(), num.isnumeric(), title.istitle()) 
False False True
In [9]:
alnum = "23apples"
num = "1234"
white = "   \t   \n\n   "
print(alnum.isalnum(), num.isnumeric(), white.isspace()) 
True True True

join(), strip(), replace(), split() metódusok

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

In [10]:
'betű' in s
Out[10]:
True
In [11]:
s.find('betű')
Out[11]:
18
hi = "how ARE you"
seq = ['h', 'o', 'w']  #OR seq = 'h', 'o', 'w'
wh = "\t this \n "
Method Description Input Output
.join() concatenates with separator string " < ".join(seq) h < o < w
.lstrip() removes leading whitespaces wh.lstrip() "this \n "
.rstrip() removes trailing whitespaces wh.rstrip() "\t this"
.strip() performs lstrip() and rstrip() wh.strip() "this"
.replace(old, new [, m]) replaces old with new at most m times hi.replace("o", "O") hOw ARE yOu
.split(s[,m]) splits at s max m times, returns list hi.split() [ "how", "ARE", "you" ]

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

In [12]:
wh = 'tab\túj sor\nszóköz'
wh.split()
Out[12]:
['tab', 'új', 'sor', 'szóköz']
In [13]:
s.split()   
Out[13]:
['hol', 'KIS-,', 'hol', 'NAGYbetűk']
In [14]:
s = "elso      masodik\tharmadik\nnegyedik" # szokozokkel szavakra vagjuk
s.split(" ")
Out[14]:
['elso', '', '', '', '', '', 'masodik\tharmadik\nnegyedik']
In [15]:
s = "elso masodik, harmadik, negyedik"
s.split(", ")            # itt egy vesszo es egy szokoz is van!
Out[15]:
['elso masodik', 'harmadik', 'negyedik']

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 = "...vesszővel kezdődik, ponttal vegződik vagy fordítva,"
print(s.strip(".,"))   # mindket vegerol
print(s.rstrip(".,"))  # csak jobbrol torol
print(s.lstrip(".,"))  # csak balrol torol
vesszővel kezdődik, ponttal vegződik vagy fordítva
...vesszővel kezdődik, ponttal vegződik vagy fordítva
vesszővel kezdődik, ponttal vegződik vagy fordítva,

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:0>8b}".format(42)
Out[23]:
'int 42,  hex 2a 2A,  oct 52,  bin 00101010'
In [24]:
"{0}, {0:e}, {0:f}, {0:10.4f}, {0:15.1f}".format(-12.345)
Out[24]:
'-12.345, -1.234500e+01, -12.345000,   -12.3450,           -12.3'
In [25]:
'A középpont: ({x:5}, {y:f})'.format(y=5, x=3)
Out[25]:
'A középpont: (    3, 5.000000)'
In [26]:
x1 = 3; y1 = 4
print('A középpont: ({x}, {y})'.format(x=x1, y=y1))
A középpont: (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: https://regex101.com/#python, https://extendsclass.com/regex-tester.html#python, https://www.regextester.com/, https://pythex.org/ (itt van puska is).

Építőelemek:

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

Jel Jelentése (mire illeszkedik) Példa Illeszkedik
. bármely karakterre illeszkedik (kivéve új sor) "t.t." tatu, tütü
^ a minta elejére illeszkedik "^Mélységes mély"
$ a minta végére illeszkedik "és bízva bízzál.\$"
| logikai vagy a környező RE-ekre "Informati(cs|ka)" Informatics, Informatika
[] a felsorolt karakterek bármelyikére illeszkedik [xq] x, q
[^chars] bármi, kivéve a felsoroltak [^xq] a, b, c,...
[a-z] tartomány "[0-9a-fA-F]" bármely hexa jegy
() hivatkozható csoportosítás
? előző RE 0 vagy egyszeri ismétlése "colou?r" color, colour
* a megelőző RE 0 vagy többszöri ismétlése "woo*w" wow, woooooow
+ a megelőző RE 1 vagy többszöri ismétlése "wo+w" wow, woooooow
*? a * lusta változata
+? a + mohó változata
{n} az előző RE pontosan n-szer "al{2}e{2}" allee
{n,} az előző RE legalább n-szer "wo{3,}w" wooow, woooow
{,n} az előző RE legföljebb n-szer
{n,m} legalább n-szer, legföljebb m-szer
\ 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

A re modul néhány függvénye:

Függvény Leírás
findall(p, s) a p minta összes előfordulása az s sztringben
search(p, s) visszaad egy „match object”-et ha p illeszkedik s egy részére
split(p, s) elvágja p minden illeszkedésénél az s sztringet, listát ad vissza
sub(p, n, s[, m]) helyettesíti p-t n-re az s-ben m-szer
finditer(p, s) "match object"-ek iterálható objektuma

A „match object” megadja, hogy a minta hol illeszkedik és mire. Ezt az infot a .span() és a .group() metódus adja vissza.

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.

In [29]:
nyers = r"aa\txx\s"
nem_nyers = "aa\txx\s"
eszkepelt = "aa\txx\\s"
print("Nyers:     " + nyers)
print("Nem nyers: " + nem_nyers)
print("Eszképelt: " + eszkepelt)
Nyers:     aa\txx\s
Nem nyers: aa	xx\s
Eszképelt: aa	xx\s
In [30]:
s = "confirmation"
p = ".i"
print(re.findall(p, s))
['fi', 'ti']
In [31]:
print(re.search(p, s))
<_sre.SRE_Match object; span=(3, 5), match='fi'>
In [32]:
x = re.search(p, s)
print(x.span())
print(x.group())
(3, 5)
fi
In [33]:
print(re.split(p, s))
['con', 'rma', 'on']
In [34]:
x = re.finditer(p, s)
for y in x:
    print(y.group(), y.span())
fi (3, 5)
ti (8, 10)
In [35]:
s = "Hú, de szép"
p = "([úé])"
print(re.sub(p, r"\1\1\1\1", s))
Húúúú, de széééép
In [36]:
s = "This 'string' has two 'quoted' words"
p1 = "'.*'"    # mohó, greedy    
p2 = "'.*?'"   # lusta, lazy
print(re.findall(p1, s), "  --> greedy")
print(re.findall(p2, s), "  --> lazy")
["'string' has two 'quoted'"]   --> greedy
["'string'", "'quoted'"]   --> lazy
In [ ]: