Ez a kérdés, illetve feladat például olyankor merül fel, ha egy személynevet tartalmazó karakterlánc csupa kisbetűvel áll rendelkezésre, de megjeleníteni a helyesírás szabályai szerint kívánjuk, azaz a családi- és utónevet nagy kezdőbetűvel akarjuk írni. Egy másik eset, ha angol nyelvű cikkben, könyvben vagy más írásműben a karakterlánc címsorként szerepel. Ilyenkor az angolban az egyes szavak kezdőbetűit szokás nagybetűvel írni. E formázási stílus neve angolul „title case”.
A Pythonban egy szöveget ilyen címsor formára hozni például a karakterláncokra meghívható beépített title() metódussal lehet, ami a szöveg minden szavának kezdőbetűjét nagybetűsre, a többit kisbetűsre cseréli. Ha tehát a szöveg „john smith”, akkor „john smith”.title() eredménye „John Smith” lesz.
Mi van azonban akkor, ha a „She’s a doctor, isn’t she?” szövegre hívjuk meg a title() metódust? Ebben az esetben az eredmény ez lesz: „She’S A Doctor, Isn’T She? „
Ez azonban nem egészen az, amit vártunk, hiszen az aposztrófok utáni betűk is nagybetűk lettek.
Ennek oka, hogy a title() metódus a szövegben a szavakat nem úgy azonosítja, hogy szónak azt tekinti, amely karaktersorokat szóközök határolnak, hanem úgy, hogy határolójelnek a nem betű karaktereket tekinti. Másképp fogalmazva, szavaknak az összefüggő olyan betűsorozatokat tekinti, amelyek karakterei az Unicode kisbetűs, nagybetűs és nagybetűs kettősbetű kategóriákba esnek. Ezek Unicode kategóriajelölései: Ll, Lu és Lt.
Hogy kicsit jobban értsük a title() metódus működését, utánozzuk le egy title() nevű függvény definiálásával! Ezt két változatban is láthatjuk alább, de a logikája mindkettőnek ugyanaz, amely az első definícióban szereplő részletes kommentekből megérthető.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import string, unicodedata def is_letter(char): return unicodedata.category(char) in {'Lu', 'Ll', 'Lt'} def title(s): """A str.title() metódussal egyező eredményt ad.""" title_case_string = '' # Az eredményként visszaadandó karakterlánc változója. previous_char = ' ' # Az aktuális karaktert megelőző karakter nyilvántartására szolgáló változó. for char in s: # Sorban egymás után kikérjük az egyes karaktereket. # Ha az aktuális karakter Ll, Lu vagy Lt kategóriába eső betű, és a megelőző karakter nem ilyen betű, akkor # ez egy új szó kezedőbetűje, ezért ezt nagybetűsre váltjuk és így adjuk hozzá a visszaadandó karakterlánchoz. # Egyéb esetben kisbetűsként adjuk a visszaadandó karakterlánchoz. if is_letter(char) and not is_letter(previous_char): title_case_string += char.capitalize() else: title_case_string += char.lower() previous_char = char return title_case_string def title(s): """A str.title() metódussal egyező eredményt ad.""" return ''.join(s[i].capitalize() if is_letter(s[i]) and not (i and is_letter(s[i - 1])) else s[i].lower() for i in range(len(s))) |
Mindkét változat használja az is_letter() nevű saját készítésű függvényt, amely annak megállapítására szolgál, hogy az argumentumként megadott karakter Ll, Lu vagy Lt kategóriába eső betű-e. Ennek eldöntéséhez felhasználtuk az unicodedata modul category() függvényét, amely a megadott karakter kategóriakódjával tér vissza. Ha ez nem egyezik a {‘Lu’, ‘Ll’, ‘Lt’} halmaz egyik elemével sem, akkor nem a title() értelmezése szerinti betűről van szó.
A title() metóduson kívül címsor formátumra alakításhoz a string modul capwords() függvénye is használható, amely a szavakat a megadható határoló jel szerint különíti el, amely alapesetben a szóköz.
A title() metódus, a saját készítésű title() függvény és a capwords() alkalmazásának eredményeit az alábbi tesztsorok mutatják.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# TESZT txt = "She's a doctor, isn't she?" print('Címsor formátummá alakítandó szöveg:', txt) print('title() metódussal:', txt.title()) print('title függvénnyel:', title(txt)) print('capwords() függvénnyel:', string.capwords(txt)) # Eredmények: # Címsor formátummá alakítandó szöveg: She's a doctor, isn't she? # title() metódussal: She'S A Doctor, Isn'T She? # title függvénnyel: She'S A Doctor, Isn'T She? # capwords() függvénnyel: She's A Doctor, Isn't She? |
Látható, hogy jelen esetben a title() metódus és az azt utánzó title() függvény azonos, de nem az igényeinknek megfelelő eredményt ad. A capwords() viszont igen.
E bejegyzés témájához a Python tudásépítés lépésről lépésre című e-könyv következő fejezetei kapcsolódnak: „Mit teszünk, amikor programozunk?” fejezetben az „Unicode röviden” és „Hogyan találjunk rá egy Unicode karakterre?” alfejezetek, valamint a „Beépített típusok nyilvános metódusai” fejezet „Sorozattípusú konténerek” alfejezetének „Karakterlánc” alcíme.