Práce s textem
ObÄas potÅ™ebujeme pracovat s textem vÃce než jen ho spojit. Budeme potÅ™ebovat text rozdÄ›lit, formátovat apod. K tomu sloužà tÅ™Ãda string, která je zabudována v základu Lua a kterou si dnes rozebereme. Tyto funkce můžete použÃvat pro práci s texty pro hru, hodnoty v XML které jsou zapsány jako text oddÄ›lený mezerou atd... V tomto Älánku vynechám funkce které pracujà s bitovými kódy pÃsmen - nemusà sedÄ›t na linuxu a zároveň windowsu, takže pro hru nepoužitelné.
string.format()
Tato funkce je velmi užiteÄná a je mocným nástrojem v úpravÄ› textů. Lze tak oÅ¡etÅ™it hodnota nil pÅ™i výpisu nápovÄ›Ä atd... Vracà nám text s tÃm, že zástupné znaky zaÄÃnajÃcà % nahradà v daném poÅ™adà hodnotami z zdalÅ¡Ãch parametrů. Jako prvnà zde uvedu tabulku zástupných znaků.
Zástupný znak | Význam |
---|---|
%c | OÄekáváno ÄÃslo jako parametr. Zástupný znak nahrazen znakem odpovÃdajÃcà ÄÃselnému kódu v parametru. |
%d | OÄekáváno ÄÃslo jako parametr. Zástupný znak nahrazen znakem ÄÃslem, které je v parametru. |
%E | OÄekáváno ÄÃslo jako parametr. Zástupný znak nahrazen znakem ÄÃslem, které je v parametru s tÃm, že na konec pÅ™idá exponent jako velké E. |
%e | Stejné jako velké E až na to, že mÃsto E v eponentu bude e. |
%f | Desetinné ÄÃslo s dlouhým rozvojem. |
%g | Desetinné ÄÃslo s kratÅ¡Ãm rozvojem. Jinak v tom nevidÃm rozdÃl oproti %f. |
%i | Celé ÄÃslo - stejné jako %d. |
%u | Nezáporné celé ÄÃslo. Pokud bude ÄÃslo záporné bude dÄ›lat blbosti. |
%o | ÄŒÃslo v oktálové (osmiÄkové) podobÄ›. Dle mého má minimálnà využitÃ. |
%x | Hexadecimálnà (Å¡estnáctková) podoba ÄÃsla s malými pÃsmeny. Dle mého nemá využitÃ. |
%X | Hexadecimálnà (Å¡estnáctková) podoba ÄÃsla s velkými pÃsmeny. Dle mého nemá využitÃ. |
%q | Prostý text v uvozovkách. |
%s | Prostý text bez uvozovek. |
Toto je seznam základnÃch parametrů pro string.format(...);. Dajà se pak využÃt i u jiných funkcà které je podporujÃ. Jejich výhodou je i možnost kombinovat je s ÄÃsly a hrát si s nima. Zde ukázka základu:
12-- promenne s hodnotami3local text = "Ahoj cislo je %d";4local cislo = 54335;5local desetinne = 5.678464;6local znak = 65;7local text2 = "Textik";89-- vypisy10print(string.format("Cele cisla: %d, %i, %u, %u",cislo,6543,6313,-6313));11-- vystup -> Cele cisla: 54335, 6543, 6313, 184467440737095453031213print(string.format("Desetinne cisla: %f, %g",desetinne,desetinne));14-- vystup -> Desetinne cisla: 5.678464, 5.678461516print(string.format("Exponencialni rozvoje: %e, %E",desetinne,desetinne));17-- vystup -> Exponencialni rozvoje: 5.678464e+000, 5.678464E+0001819print(string.format("Jine tvary cisel: %o, %x, %X",cislo,cislo,cislo));20-- vystup -> Jine tvary cisel: 152077, d43f, D43F2122print(string.format("Text jako vystup: %s, %q, %c",text2,"Ahoj ja jsem v uvozovkach",znak));23-- vystup -> Text jako vystup: Textik, "Ahoj ja jsem v uvozovkach", A2425print(string.format(text,cislo));26-- vystup -> Ahoj cislo je 54335
VÅ¡imnÄ›te si, že promÄ›nná která má v textu zástupný parametr ho zmÄ›nà také pokud ji formátujeme. To je znaÄná výhoda
Omezovánà parametrů
UrÄitÄ› jste si ve hÅ™e vÅ¡imli, že né vÅ¡echny desetinná Äásla se vypisujà celá, ale tÅ™eba zaokrouhlená jen na 2 desetinná mÃsta. Komu by se taky chtÄ›lo ÄÃst nevzhledné sedmimÃstné desetinné ÄÃslo? A právÄ› k takovému "zhezÄenÃ" sloužà omezenà parametrů. Funguje pro ÄÃselné parametry %f a %g. Omezenà ÄÃsla se dÄ›lá tak, že mezi procento (%) a zástupný znak se vložà ÄÃslo, které reprezentuje jeho délku. PÅ™Ãkladem je parametr %.2f, který zajistà to, že výsledné ÄÃslo bude "oÅ™Ãznuto" dvÄ› cifry za desetinnou Äárkou.
PÅ™Ãklad:
12-- Skareda desetinna promenna s celociselnou3local desetinna = 18646.68468416146463416;45-- vypis6print(string.format("Desetinna omezena: %.2f",desetinna));
string.find();
Funkce string.find(); se použÃvá zejména u instalaÄnÃch skriptů, ale využÃt e dá i jinde. VstupnÃmi parametry je Å™etÄ›zec (text), hledaná fráze, nepovinný index zaÄátku, Ätvrtý parametr si ukážeme nÄ›kdy pozdÄ›ji. Funkce dÄ›lá to že hledá danou frázi v zadaném Å™etÄ›zci od daného indexu a vracà nám dvojici promÄ›nných udávajÃcÃch start a konnec fráze v textu. Sice nám funkce nevrátà vÅ¡echny výskyty, ale dÃky vracenému parametru konce se můžeme posunou dopÅ™edu a pokraÄovat v hledánà dalÅ¡Ã fráze.
Ukázkový pÅ™Ãklad string.find();:
1-- Nas text2local text = "Ahoj, ja jsem hodne dlouhy text ve kterem budeme neco hledat.";34-- ulozeni do promennych5local start,konec = string.find(text,"te");6print("Vystup prvniho te v retezci: "..string.format("%d, %d",start,konec));78-- vypis primo9print("Vystup prvniho te v retezci: "..string.format("%d, %d",string.find(text,"te")));1011-- vsechny "te" v retezci12start = nil;13konec = 1;14repeat15 start,konec = string.find(text,"te",konec);16 if start ~= nil then17 print("Vystup te v retezci: "..string.format("%d, %d",start,konec));18 end;19until start == nil;20
string.upper() a string.lower()
Tyto dvÄ› funkce majà jeden vstupnà parametr - text - a jeden výstup - taky text. string.upper(); zmÄ›nà vÅ¡echna pÃsmena na velká. Naopak string.lower(); zmÄ›nà vÅ¡echna pÃsmena na malá. Jednoduchý pÅ™Ãklad ukáže.
12print(string.upper("jsem moc velky"));3-- V logu: JSEM MOC VELKY45print(string.lower("A JA JSEM MOC MALY"));6-- V logu: a ja jsem moc maly7
string.gsub();
Jedná se o velmi komplexnà funkce a proto doufám že ji pochopÃte. Funkce má vstrupnà parametry Å™etÄ›zec, hledaný výraz, pÅ™episovacà výraz a nepovinný poÄet provedenÃ. Funkce projde Å™etÄ›zec a nahradà každý hledaný výraz výrazem pÅ™episovacÃm. Velice jednoduchý pÅ™Ãklad použità funkce:
12-- promenne rovnou s funkci3local vysledek,pocetZmen = string.gsub("Hello banana", "banana", "Lua user");45-- vysledny text6print(vysledek);7-- zobrazeni poctu zmen8print("Pocet zmen pred vypsanim vylsdku: "..pocetZmen);9--[[10Vysledek v logu bude:1112Hello Lua user13Pocet zmen pred vypsanim vylsdku: 11415]]--16
Nynà si ukážeme použità nepovinného parametru:
12-- promenne rovnou s funkci3local maxZmen = 3;4local vysledek,pocetZmen = string.gsub("Ahoj ja jsem retezec s moc j", "j", "x",maxZmen);56-- vysledny text7print(vysledek);8-- zobrazeni poctu zmen9print("Pocet zmen pred vypsanim vylsdku: "..pocetZmen);10--[[11Vysledek v logu bude:1213Ahox xa xsem retezec s moc j14Pocet zmen pred vypsanim vylsdku: 31516]]--17
Toto jse lehké že? Nynà se tedy kouknem na nÄ›co složitÄ›jÅ¡Ãcho - použità pÅ™edávánà parametrů u této funkce. Funguje to tak, že obalÃme hledaný výraz závorkami a podle poÅ™adà závorek máme k dispozici parametry %1, %2, %3 ... %n. Ty pak můžeme použÃt pro znovuvypsánà s nÄ›jakým dodatkem. Ukážu:
12-- jednoduche s jednim parametrem3local vysledek,pocetZmen = string.gsub("Hello banana", "(banana)", "Lua user - or maybe %1?");456print(vysledek);7-- Hello Lua user - or maybe banana?89print("Pocet zmen pred vypsanim vysledku: "..pocetZmen);10-- Pocet zmen pred vypsanim vysledku: 11112-- kombinace vice parametru (otoceni pismenek)13print(string.format("%s",string.gsub("oh oh oh", "(o)(h)", "%2%1")));14-- ho ho ho15
Toto bylo použità takového speciálnÃho zástupného znaku - ale co když potÅ™ebujeme Å™etÄ›zec zpracovat jeÅ¡tÄ› vÃce a nestaÄà nám k tomu toto? Co když mám Å™etÄ›zec s instrukcemi a chci je spouÅ¡tÄ›t. Možná že to nikdy nevyužijete, ale ÄlovÄ›k nikdy nevÃ. Tato metoda se dÄ›lá tak, že mÃsto pÅ™episovacÃho parametru použiju anonymnà funkci. To je funkce která nemá název a volá se pÅ™Ãmo na řádku k nÄ›jaké Äinnosti. Na pÅ™Ãkladu pochopÃte:
12-- nulovani promenne3local pocetE = 0;45-- pouziti anonymni funkce jako parametr6local vysledek,_ = string.gsub("Ahoj ja jsme tvuj retezec.","e",function(znak)7 -- tu je kod anonymni funkce8 pocetE = pocetE + 1;9 -- a vracim znak - muzu vratit i neco jineho10 -- toto pocita pismena v retezci11 return znak;12end13);1415-- vypsani textu16print(vysledek);17-- vypsani poctu znaku - muzu pouzit i navratovou hodnotu18-- ale zde si ukazujeme kod v anonymni funkci19print(pocetE);20
Tak a nynà si ukážeme použità zachytávánà jakkoli dlouhého textu mezi nÄ›jakými zástupnými znaky. K tomu se použÃvá dvou konstruncÃ:
(.-) - zachytà minimálnà poÄet znaků mezi zástupnými znaky. PÅ™Ãklad: {(.-)} zachytà vÅ¡echny znaky mezi složenými závorky.
(.*) - zachytà maximálnà poÄet znaků mezi zástupnými znaky. PÅ™Ãklad: {(.*)} zachytà vÅ¡echny znaky od prvnà do poslednà složené závorky v textu.
Nynà si tyto konstrukce ukážeme na pÅ™Ãkladu.
12-- text3local text = "Ahoj ja jsem tvuj text {a jsem velmi dlouhy}";45-- nahrazeni textu necim jinym6local v,_ = string.gsub(text,"{(.-)}",function(a)7 return string.upper(a);8end9);1011-- vypis vysledku12print(v);13-- log: Ahoj ja jsem tvuj text A JSEM VELMI DLOUHY14
string.len();
Funkce má jeden vstupnà parametr - text. Jako výstup vracà délku zadaného textu (poÄet znaků).
12-- ulozeni do promenne3local delka = string.len("Vitej programatore");4print(delka);5-- v logu: "18"6
string.rep();
Funkce opakuje Å™etÄ›zec nkrát. VtupnÃmy parametry je text a kolikrát se má opakovat. Výsledkem je Å™etÄ›zec který se buÄ ukládá do promÄ›nné nebo rovnou vypisuje.
12-- opakovani a rovnou ulozeni do promenne3local vysledek = string.rep("Vitejte v LUA!\n",5);45print(vysledek);6--[[7LOG:8Vitejte v LUA!9Vitejte v LUA!10Vitejte v LUA!11Vitejte v LUA!12Vitejte v LUA!1314]]--15
VÅ¡imnÄ›te si, že aby se mi to nezkopÃrovalo za sebe na řádek, použil jsem zástupný znak pro enter a to sice . K podobným znakům se budeme dostávat v průbÄ›hu.
string.sub();
Tato funkce vracà výňatek z textu. VstupnÃmy parametry je text, ZaÄátek výbÄ›ru a nepovinný konec výbÄ›ru. Pokud nenà urÄen konec výbÄ›ru, funkce vrátà vÅ¡e od zaÄátku výbÄ›ru až po konec textu. Ukážu pÅ™Ãklad.
12-- Bez koncoveho parametru3local vynatek = string.sub("Ahoj priteli muj.",6);4print(vynatek);5-- "priteli muj."67-- S koncovym parametrem8local vynatek = string.sub("Ahoj priteli muj.",6,12);9print(vynatek);10-- "priteli"11
VÅ¡imnÄ›te si, že vybrané znaky jsou s parametry vÄetnÄ›. TudÞ když do prvnÃho parametru zadám ÄÃslo 1, bude se zaÄÃnat prvnÃm pÃsmenem.
string.reverse();
Vrátà text obráceně. Jediný vstup je text a výstupem je ten samý text, akorát obráceně. Jednoduchá ukázka:
12local obracene = string.reverse("Kuna nese nanuk");3print(obracene);4-- "kunan esen anuK"
string.match();
Hledá text v textu podle zadaných parametrů. Znà to krkolomnÄ› ale výsledek je naprosto logický. Můžeme hledat také podle vÃce parametrů naráz. VstupnÃmi promÄ›nnými je Å™etÄ›zec, hledaný text a nepovinný poÄáteÄnà index. Pro hledaný text platà stejné pravidla jako pro hledaný text ve funkci gsub s tÃm, že zde se využije vÃce rozÅ¡ÃÅ™ených podmÃnek. RozÅ¡ÃÅ™ené podmÃnky jsou %d+ pro ÄÃslo delÅ¡Ã než 1 znak, %a+ pro text delÅ¡Ã než 1 znak (alfanumerický) a %s pro jeden znak textu. Můžeme samozÅ™ejmÄ› použÃt pÅ™esné znÄ›nà hledaného textu, ovÅ¡em to tu nelze moc použÃt, protože vÄ›tÅ¡inou chceme hledat obecnÄ›. Pokud nenajde Å™etÄ›zec vrátà nil.
12local promenna = string.match("Mam tu 5 tun psenice","%d+ %a+ %a+");3print(promenna);4-- "5 tun psenice"5
string.gmatch();
Tato funkce je iterátorem. Proto se použÃvá v generickém cyklu for. Použità je tady stejné jako pairs nebo ipairs. Vracà jednu hodnotu a to sice aktuálnà platný hledaný výraz, který se pokusà najÃc co nejvÃcekrát v zadaném textu a každou možnost projde. Teoreticky může vracet vÃce hodnot ale to nÄ›kdy pÅ™ÃÅ¡tÄ›. Nynà pÅ™Ãlad:
12local text = "Ahoj 52, dnes tu mam cisla 12,5,8,62,31";3local soucet = 0;4for cislo in string.gmatch(text, "%d+") do -- vyhledam vsechny cisle5 soucet = soucet + cislo;6end;7print("Soucet cisel v textu: "..soucet);8-- "Soucet cisel v textu: 170"9
Co se stalo? ProÅ¡li jsme text a stÃm, že jsme hledali každé ÄÃslo vÄ›tÅ¡Ã nebo rovno jedné ÄÃslici. Každé takové ÄÃslo bylo pÅ™iÄteno k celkovému souÅ¡tu který byl následnÄ› po skonÄenà cyklu vypsán.