10. diel - Textové reťazce v VB.NET do tretice - Split a Join
V predchádzajúcom cvičení, Riešené úlohy k 9. lekcii VB.NET, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
Dnes si vo Visual Basic .NET tutoriálu vysvetlíme ďalšie metódy na
reťazci, ktoré som vám zámerne zatajil, pretože sme nevedeli, že
String
je vlastne pole:)
Na reťazci môžeme používať mnoho metód, ktoré poznáme z poľa. Sú
to napr: First()
, Last()
, IndexOf()
a
ďalšie.
Keď si vytvoríte ľubovoľnú premennú a napíšete za ňu potom bodku, zobrazí vám Visual Studio ponuku všetkých metód a vlastností (a tiež premenných, ale k tomu sa dostaneme až pri objektoch), ktoré na ňu môžete volať. Tomuto nástroju sa hovorí IntelliSense a spríjemnia vám prácu s kódom, ktorý za vás dopĺňa. Skúsme si to:
Tú istú ponuku možno vyvolať aj stlačením Ctrl + Medzerník v prípade, že kurzor umiestnime na bodku. Samozrejme to platí pre všetky premenné aj triedy a budeme toho využívať čoraz častejšie. Metódy sú radené abecedne a môžeme nimi listovať pomocou kurzorových šípok. VS nám zobrazuje opis metód (čo robia) a aké majú parametre.
Povedzme si o nasledujúcich metódach a ukážme si ich na jednoduchých príkladoch:
Ďalšie metódy na reťazci
Insert()
Vloží podreťazec do reťazca na určitú pozíciu. Parametre sú pozície v reťazci a podreťazec.
{VBNET_CONSOLE}
Console.WriteLine("Punk's dead".Insert(7, "not "))
{/VBNET_CONSOLE}
výstup:
Konzolová aplikácia
Punk's not dead
Remove()
Vymaže znaky od danej pozície do konca. Parametrom je číselná pozícia. Môžeme zadať druhý parameter, ktorým je počet znakov, ktoré chceme vymazať.
{VBNET_CONSOLE}
Console.WriteLine("Michael Jackson".Remove(7, 5))
{/VBNET_CONSOLE}
výstup:
Konzolová aplikácia
Michaelson
Substring()
Vráti podreťazec od danej pozície do konca reťazca. Môžeme zadať druhý parameter, ktorým je dĺžka podreťazca.
{VBNET_CONSOLE}
Console.WriteLine("Wolfgang Amadeus Mozart".Substring(9, 7))
{/VBNET_CONSOLE}
výstup:
Konzolová aplikácia
Amadeus
CompareTo()
Umožňuje porovnať dva reťazce podľa abecedy. Vracia -1
ak
je prvý reťazec pred reťazcom v parametri, 0
ak sú rovnaké a
1
ak je za ním:
{VBNET_CONSOLE}
Console.WriteLine("Argentina".CompareTo("Barbados"))
{/VBNET_CONSOLE}
výstup:
Konzolová aplikácia
-1
Poďme sa teraz pozrieť na 2 ďalšie metódy na type String
,
ktoré sú naozaj veľmi užitočné.
Split()
a Join()
Z predchádzajúceho tutoriálu vieme, že parsování reťazca po znaku
môže byť niekedy celkom zložité a to sme robili pomerne jednoduchý
príklad. S reťazci sa samozrejme budeme stretávať stále, a to ako na vstupe
od užívateľa (napr. Z konzoly alebo z polí v okenných aplikáciách), tak v
súboroch TXT a XML. Veľmi často máme zadaný jeden dlhší
String
(riadok súboru alebo riadok konzoly), v ktorom je viac
hodnôt, oddelených tzv. Separátory, napr. Čiarkou. V tomto prípade
hovoríme o formáte CSV (Comma-Separated Values, teda hodnoty oddelené
čiarkou). Aby sme si boli istí, že vieme, o čom hovoríme, ukážme si
nejaké ukážkové reťazca:
Jan, Novák, Dlhá 10, Praha 3,130 00 .. ... .-.. .- -. -.. ... --- ..-. - (1,2,3;4,5,6;7,8,9)
Prvý reťazec je očividne nejaký užívateľ, takto by sme mohli napr.
Realizovať uloženie užívateľov do CSV súboru, každý na jeden riadok.
Druhý reťazec sú znaky Morseovej abecedy, separátor (oddeľovač) je tu
medzera.
Tretí reťazec je matica o 3 stĺpcoch a 3 riadkoch. Oddeľovač stĺpcov je
čiarka, riadok bodkočiarka
Na premenných typu String
môžeme volať metódu
Split()
, ktorá berie ako parameter separátor (Char
),
prípadne dokonca pole separátorov. Následne pôvodnej
reťazec rozdelí podľa separátorov na pole podreťazcov, ktoré vráti. To
nám veľmi uľahčí prácu pri rozdeľovaní hodnôt v reťazci.
Metóda Join()
sa volá priamo na type String
a
umožňuje nám naopak pole podreťazcov spojiť oddeľovačom do jediného
reťazca, parametre sú oddeľovač a polia. Výstupom metódy je výsledný
reťazec.
Keďže nevieme tvoriť objekty (používateľa) a ani pracovať s viacrozmernými poliami (matice), skúsime si naprogramovať dekodér správ z Morseovej abecedy.
Dekodér Morseovej abecedy
Poďme si opäť pripraviť štruktúru programu. Budeme potrebovať 2
reťazca so správou, jeden so správou v Morseovej abecede, druhý zatiaľ
prázdny, do ktorého budeme ukladať výsledok nášho snaženia. Ďalej budeme
ako v prípade samohlások potrebovať nejaký vzor písmen. K písmenám
samozrejme vzor ich znaku v morzeovce. Písmená môžeme opäť uložiť ako
púhy String
, pretože majú len jeden znak. Znaky Morseovej
abecedy majú už znakov viac, tie musíme dať do poľa. Štruktúra nášho
programu by teraz mohla vyzerať nasledovne:
' reťazec, ktorý chceme dekódovať Dim s As String = ".-.. . --- -. .- .-. -.. ---" Console.WriteLine("Pôvodná správa: {0}", s) ' reťazec s Dekódovanie správou Dim zprava As String = "" ' vzorová pole Dim abecedniZnaky As String = "abcdefghijklmnopqrstuvwxyz" Dim morseovyZnaky() As String = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."}
Môžete si potom pridať ďalšie znaky ako čísla a interpunkčné
znamienka, my ich tu vynecháme. Teraz si reťazec s
rozbijeme
metódou Split()
na pole reťazcov, obsahujúcich jednotlivé znaky
morzeovky. Splitová budeme podľa znaku medzery. Pole následne proiterujeme
cyklom For Each
:
' rozbitie reťazca na znaky morzeovky Dim znaky() As String = s.Split(" ") ' iterácie znaky morzeovky For Each morseuvZnak As String In znaky Next
Ideálne by sme sa mali nejako vysporiadať s prípadmi, kde užívateľ
zadá napr. Viac medzier medzi znakmi (to užívatelia radi robia).
Split()
potom vytvorí o jeden reťazec v poli viac, ktorý bude
prázdny. Ten by sme mali potom v cykle detekovať a ignorovať, my sa s tým v
tutoriálu nebudeme zaoberať.
V cykle sa pokúsime nájsť aktuálne čítaný znak morzeovky v poli
morseovyZnaky
. Bude nás zaujímať jeho index,
pretože keď sa pozrieme na ten istý index v poli abecedniZnaky
,
bude tam zodpovedajúce písmeno. To je samozrejme z toho dôvodu, že ako pole
tak reťazec obsahujú rovnaké znaky, zoradené podľa abecedy. Umiestni do
tela cyklu nasledujúci kód:
Dim abecedniZnak As Char = "?" Dim index As Integer = Array.IndexOf(morseovyZnaky, morseuvZnak) If index >= 0 Then ' znak nájdený abecedniZnak = abecedniZnaky(index) End If zprava &= abecedniZnak
Kód najprv do abecedného znaku uloží "?"
, Pretože sa môže
stať, že znak v našej sade nemáme. Následne sa pokúsime zistiť jeho
index. Ak sa to podarí, dosadíme do abecedniZnak
znak z
abecedných znakov pod týmto indexom. Nakoniec znak pripojíme k správe.
Operátor &=
nahrádza
zprava = zprava & abecedniZnak
.
Záverom samozrejme správu vypíšeme a pridáme ReadKey()
:
{VBNET_CONSOLE}
' reťazec, ktorý chceme dekódovať
Dim s As String = ".-.. . --- -. .- .-. -.. ---"
Console.WriteLine("Pôvodná správa: {0}", s)
' reťazec s Dekódovanie správou
Dim zprava As String = ""
' vzorová pole
Dim abecedniZnaky As String = "abcdefghijklmnopqrstuvwxyz"
Dim morseovyZnaky() As String = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
"..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-",
"...-", ".--", "-..-", "-.--", "--.."}
' rozbitie reťazca na znaky morzeovky
Dim znaky() As String = s.Split(" ")
' iterácie znaky morzeovky
For Each morseuvZnak As String In znaky
Dim abecedniZnak As Char = "?"
Dim index As Integer = Array.IndexOf(morseovyZnaky, morseuvZnak)
If index >= 0 Then ' znak nájdený
abecedniZnak = abecedniZnaky(index)
End If
zprava &= abecedniZnak
Next
Console.WriteLine("Dekódovaná správa: {0}", zprava)
Console.ReadKey()
{/VBNET_CONSOLE}
Konzolová aplikácia
Pôvodná správa: .-.. . --- -. .- .-. -.. ---
Dekódovaná správa: leonardo
Hotovo! Za úlohu máte si naprogramovať program opačný, ktorý naopak
zakóduje reťazec do morzeovky, kód bude veľmi podobný. So
Split()
a Join()
sa stretneme počas seriálu ešte
niekoľkokrát.
Špeciálne znaky alebo uvádzacích
Textový reťazec môže obsahovať viac riadkov alebo napríklad
tabulátormi. Špeciálnych znakov je ešte viac, ale nebudeme si ich tu všetky
zmieňovať. Nový riadok do reťazca vložíme pomocou konštanty
vbCrLf
a tabulátor pomocou vbTab
. Poďme si to
vyskúšať:
{VBNET_CONSOLE}
'Prvú možnosť
Console.WriteLine("Prvý riadok{0}Druhý riadok", vbCrLf)
'Druhá možnosť
Console.WriteLine("Prvý riadok" & vbCrLf & "Druhý riadok")
'Obe fungujú a robia to isté.
Console.ReadKey()
{/VBNET_CONSOLE}
VB.NET do textu vloží 2 znaky a to CR a LF. Ak ste sa zaujímali o ASCII
tabuľku, tak viete, že to sú práve znaky ASCII, konkrétne CR má číslo
13
a LF 10
. Ukončovanie riadkov týmito dvoma znakmi
má pôvod v starých tlačiarňach, kde jeden znak označoval návrat tlačovej
hlavy (Carriage Return) na začiatok riadka a druhý posun papiera nadol (Line
Feed). Úplne to isté sa stane ak napíšete:
{VBNET_CONSOLE}
Console.WriteLine("Prvý riadok{0}Druhý riadok", Chr(13) & Chr(10))
'Druhá možnosť
Console.WriteLine("Prvý riadok" & Chr(13) & Chr(10) & "Druhý riadok")
'Obe fungujú a robia to isté.
Console.ReadKey()
{/VBNET_CONSOLE}
Ak by ste niekedy potrebovali dvojité úvodzovky v reťazci, napíšete je ako dvoje dvojité úvodzovky. VB.NET si ich tak nepopletie s koncom reťazca. Takéto technike odstránenie špeciálneho významu nejakého znaku sa všeobecne hovorí uvádzacích.
{VBNET_CONSOLE}
Console.WriteLine("Toto je úvodzovky: """)
{/VBNET_CONSOLE}
Týmto sme v podstate zakončili sekcii sa základné štruktúrou jazyka VB.NET.
V nasledujúcom cvičení, Riešené úlohy k 10. lekcii VB.NET, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.