Łańcuchy
Adam Boduch
Jeżeli możesz popraw ten artykuł według zaleceń, które możesz znaleźć na stronie [[Artykuły do poprawy]]. Po dopracowaniu tego tekstu można usunąć ten komunikat.
W tym artykule omówię funkcję operujące na tekście. Będą one umożliwiały takie działania jak dodawanie w wybrane pozycje jakichś znaków, odnajdywanie określonych wyrazów, zmianę tekstu na liczby (lub odwrotnie) i inne.
1 Przydatne Metody
1.1 Copy
1.1.1 LeftStr, RightStr
1.2 Length
1.3 Pos
1.4 PosEx
1.4.2 Lewostronne PosEx
1.5 Delete
1.6 Insert
1.7 Format
1.8 ExtractStrings
1.9 Inne
1.9.3 Concat
1.9.4 StringOfChar
1.9.5 Trim
1.9.6 UpperCase, LowerCase
1.9.7 ReverseString
1.10 Ćwiczenie
2 Konwersje łańcuchów
2.11 Zmiana z/na liczby
2.12 Kody znaków ASCII
2.13 Wartości Logiczne
2.14 Data
2.14.8 StrToDate
2.14.9 StrToTime
3 Zakończenie
Przydatne Metody
Copy
Copy służy ono do kopiowania części znaków ze zmiennej.var
S, Finall : String;
begin
S := 'Adres strony: http://4programmers.net';
Finall := Copy(S, 1, 6) + 'e-mail: boduch@poland.com';
ShowMessage(Finall);
end;
Mamy sobie dwa stringi. Teraz do drugiego kopiujemy kawalek tekstu z pierwszego. W poleceniu Copy pierwszym parametrem musi być źródło wykonywanej operacji, drugi parametr to miejsce od którego będzie się zaczynała operacja kopiowania, a ostatni to ilość znaków do skopiowania.
LeftStr, RightStr
Te funkcje zwracają kawałek tekstu po odpowiednio lewej i prawej stronie. Drugim parametrem jest ilość znaków które zostaną skopiowane. Funkcje różnią się tylko tym, że w LeftStr kopiowanie zaczyna się od lewej strony, a w RightStr od prawej.var
S : String;
begin
S := ' Jeden Dwa Trzy Cztery Pięć';
ShowMessage(LeftStr(S, 6)); //Zobaczymy "Jeden"
ShowMessage(RightStr(S, 11)); //Zobaczymy "Cztery Pięć"
end;
Jeżeli łańcuch zawiera wielobajtowy tekst, funkcja może zwrócić inną ilość znaków niż podano w parametrze. Funkcjami pochodnymi są LeftBStr oraz RightBStr, które traktują wszystkie znaki jako jednobajtowe.
Length
Dość często używana funkcja, to [[Delphi/Length]]. Zwraca długość tekstu. ```delphi var S : String; begin S := 'Delphi'; Length(S); //Zwróci 6 end; ```Length służy też do zwracania ilości elementów w tablicy.
Pos
Kolejne bardzo przydatne polecenie. Otóż umożliwia ono przeszukiwanie określonego ciągu znaków w jakiejś zmiennej tekstowej. Przykładowo chciałbyś w jakiejś zmiennej odnaleźć spacje. ```delphi var S : String; begin S := 'Tekst zawierający spacje'; if Pos(' ', S) > 0 then //Jeżeli ciągu znaków nie ma w zmiennej, Pos zwróci 0 ShowMessage('W zmiennej znajdują się spacje.'); end; ``` W poleceniu Pos pierwszym parametrem jest szukany znak, a drugim źródło poszukiwań, czyli jak w naszym przykładzie zmienna S. W powyższym przykładze program poszukuje spacji w zmiennej. Jeżeli pozycja spacji będzie większa niż 0 (tzn. jeżeli tak jest) to wyświetla komunikat. Polecenie Pos używa się często w połączeniu z innymi - pokażemy to dalej...PosEx
Następne polecnie jest bardzo podobne do zwykłego Pos'a z tym, że posiada pewien dodatkowy parametr - miejsce od którego chcemy zacząć szukać. ```delphi var S: String; begin s:= 'aaaa * bbbb * cccc'; PosEx('*', s, 7); end; ``` Otrzymamy wynik: 13, kiedy Pos() zwróciło by nam 6.Pos(S, S2);
//jest równoważne
PosEx(S, S2, 1);
Lewostronne PosEx
Wiem z doświadczenia że czasami przy zabawie z łańcuchami przydałoby się znaleźć jakiś tekst który znajduje się nie **za** tekstem odniesienia (tak jak w przypadku funkcji [[Delphi/Pos]] i [[Delphi/PosEx]]) a **przed** nim. Takiej funkcji nie ma w potężnych modułach VCL, więc napisałem ją sobie sam.function PosExBack(aSubStr, aStr: String; aOffset: Integer): Integer;
var Res: Integer;
begin
Result := 0;
Res := 0;
aStr := Copy(aStr, 1, aOffset);
repeat
Res := PosEx(aSubStr, aStr, Res + 1);
if Res > 0 then Result := Res;
until Res = 0;
end;
Działa tak samo jak zwykłe PosEx, tylko że nie szuka tekstu za aOffset tylko przed nim.
Delete
Kolejne polecenie służy do usuwania określonego ciągu znaków ze zmiennej. Pierwszym jego parametrem jest zmienna, której dotyczyć będzie operacja, drugim od jakiego miejsca w zmiennej będzie dotyczyć usuwania, a ostatni parametr to ilość znaków do usunięcia:var
S : String;
begin
S := 'Adres strony: http://4programmers.net';
Delete(S, 1, 21);
ShowMessage(s);
end;
Powyższa procedura wyświetli jedynie napis 4programmers.net
(bez http://
). Gdy już wiesz o co chodzi w poleceniu Delete oraz Pos można napisać procedurę usuwającą wszystkie spacje w zmiennej:
var
S : String;
begin
S := 'Tekst zawierający spacje';
while Pos(' ', S) > 0 do
Delete(S, Pos(' ', S), 1);
ShowMessage(S);
end;
Powyższe komendy usuną wszystkie spacje w zmiennej i ponownie wyświetlą stringa. Zastosowanie tutaj pętli spowoduje, że na pewno wszelkie spacje zostaną usunięte.
Insert
Parametry w tej procedurze są trochę pomieszane dlatego, że jej pierwszym parametrem jest ciąg znaków, który ma być wstawiony, drugim jest źródło operacji, czyli zmienna, której dotyczyć będzie operacja, a ostatni - trzeci parametr to znak od którego zaczynać się będzie operacja dodawania ciągu:var
S : String;
begin
S := 'Adres strony: 4programmers.net';
Insert('http://', S, 15);
ShowMessage(s);
end;
Format
Ta funkcja jest bardzo przydatna, gdyż umożliwia formatowanie tekstu.var
ImieKolegi, MojeImie: String;
Wiek: Integer;
begin
ImieKolegi := 'Bożydar';
MojeImie := 'Gerwazy';
Wiek := 17;
ShowMessage(Format('Witaj %s, nazywam się %s i mam %d lat', [ImieKolegi, MojeImie, Wiek]));
end;
Zobaczymy oczywiście Witaj Bożydar, nazywam się Gerwazy i mam 17 lat
. Może wygląda to skomplikowanie, ale w rzeczywistości to bardzo proste. Pierwszy parametr to tekst, która ma w sobie dziwne człony (mówię o %s
i %d
). W te miejsca zostaną po kolei ? wepchnięte ? łańcuchy z drugiego parametru. A co znaczą litery s
i d
? Te symbole odpowiadają odpowiednio stringowi i liczbie rzeczywistej. Więcej informacji w artykule Format.
ExtractStrings
Funkcja rozdziela łańcuch (trzeci parametr) według separatora/ów (pierwszy parametr), pomija tzn. "white spaces" (drugi parametr), i zapisuje do jakiejś zmiennej (czwarty parametr) np do [[Delphi/TStrings]], [[TStringList]] etc.var
TS: TStringList;
begin
ExtractStrings([' '], [], 'jacek wacek placek lol', Memo1.Lines);
end;
Taki kod zapisze do Memo tekst:
jacek
wacek
placek
lol
gdyby w drugim parametrze zamiast []
podać [#32]
(kod spacji, czyli po prostu [' ']
) tekst wyglądały tak:
jacek
wacek
placek
lol
Inne
Istnieją jeszcze mniej przydatne polecenia, rzadziej używane. Wymienię je poniżej.Concat
Na początek polecenie Concat umożliwiające połączenie określonych wyrazów (bloków). Polecenie to jest bardzo rzadko stosowane bo zastępuje ono częściej używany operator + służący właśnie do łączenia znaków. Oto przykład:var
S: String;
begin
S := '15 czerwca';
ShowMessage(Concat('Dzisiaj jest ', S, ' roku 2012'));
end;
Nic nadzwyczajnego. Jedyne chyba jej zastosowanie to efekt estetyczny kodu, jeżeli łączymy więcej stringów.
StringOfChar
Nie robi ono nic specjalnego. Wpisz do programu taki kod: ```delphi ShowMessage(StringOfChar('A', 5)); ``` a zobaczysz `AAAAA`.Bardzo podobną funkcją jest DupeString, z tym że umożliwia ona kopiowanie całych łańcuchów (nie tylko pojedynczych znaków).
Trim
Funkcja nie robi nic oprócz obcinania spacji na początku i na końcu stringa:var
S : String;
begin
S := ' Adam Boduch ';
ShowMessage(Trim(S)); //Zobaczymy samo "Adam Boduch"
end;
UpperCase, LowerCase
Te funkcje zmieniają litery w łańcuchu na duże ([[Delphi/UpperCase]]) oraz na małe ([[Delphi/LowerCase]]) litery.ShowMessage(UpperCase('http://4programmers.net')); //Zobaczymy "HTTP://4PROGRAMMERS.NET"
ShowMessage(LowerCase('BODUCH@POLAND.COM')); //Zobaczymy "boduch@poland.com"
ReverseString
Jak można wywnioskować po nazwie, funkcja zwraca odwrócony ciąg znaków. Po wywołaniu tego: ```delphi var S : String; begin S := ' Odwróć Mnie'; ShowMessage(ReverseString(S)); end; ``` Zobaczymy okienko z napisem "einM ćórwdO".Ćwiczenie
Myślę, że dobrym podsumowaniem tego co dotychczas zrobiliśmy będzie program, który 'wygrzebie' ze stringa adres e-mail:var
AtPos, LeftSidePos, MailLength, I: Integer;
sText: String;
begin
AtPos := Pos('@', sText);
if AtPos > 1 then
begin
LeftSidePos := AtPos;
while (sText[LeftSidePos - 1] in ['a'..'z', 'A'..'Z', '0'..'9', '-', '_', '.']) do
Dec(LeftSidePos);
MailLength := 0;
while (sText[AtPos + MailLength + 1] in ['a'..'z', 'A'..'Z', '.']) do
Inc(MailLength);
ShowMessage(Copy(sText, LeftSidePos, AtPos - LeftSidePos + MailLength + 1));
end
else
ShowMessage('Podany tekst nie ma w sobie maila');
end;
Budowa nie jest zbyt skomplikowana. Na początek program w zmiennej odnajduje znak małpy, a później 'cofa się' w zmiennej aż napotka znak który nie może znajdować się w adresie. Następnie idzie od małpy do znaku który nie może znajdować się w domenie.
Konwersje łańcuchów
Zmiana z/na liczby
Do zmiany łańcucha na liczby i odwrotnie służą funkcje StrToInt oraz IntToStr.
var
S: String;
I: Integer;
begin
S := '25';
I := StrToInt(S); //Teraz w I jest liczba 25
ShowMessage(IntToStr(I));
end;
A co w przypadku jeżeli w S nie będzie liczby, albo będą oprócz niej inne znaki, np siema
? W takim wypadku kompilator wyrzuci nam błąd 'siema' is not vaild Integer value
. Możemy się przed tym zabezpieczyć dzięki takim funkcjom jak TryStrToInt lub StrToIntDef.
Istnieją odpowiedniki tych funkcji dla liczb zmiennoprzecinkowych, a są to StrToFloat oraz FloatToStr:
var
S: String;
D: Double;
begin
S := '25.5';
D := StrToFloat(S); //Teraz w D jest liczba 25.5
ShowMessage(FloatToStr(D));
end;
Dla tych funkcji również są ? bezpieczne ? odpowiedniki: TryStrToFloat i StrToFloatDef.
Kody znaków ASCII
Do zabawy takimi kodami służą funkcje [[Delphi/Ord]] oraz [[Delphi/Chr]]. Zamieniają one kolejno, znak na jego kod oraz odwrotnie.var
C: Char;
I: Integer;
begin
C := 'A';
ShowMessage(IntToStr(Ord(C))); //Zobaczymy "65" > kod znaku "A";
{Najpierw zamienimy to co jest w C ("A") na kod, następnie powiększymy o dwa, i znów zapiszemy}
C := Chr( Ord(C) + 2); //Zwróci "C"
end;
Wartości Logiczne
Nie dla każdego te słowa są zrozumiałe. Wartości Logiczne to `True`/`False` (Prawda/Fałsz). Przykład takiej konwersji:begin
BoolToStr(True); //Zwraca "0"
BoolToStr(False); //Zwraca "-1"
end;
Ta funkcja posiada jeszcze jeden parametr, jeżeli przyjmie on wartość True
wtedy zwróci nam angielskie słowa odpowiadające wartościom.
begin
BoolToStr(True, True); //Zwraca napis "True"
BoolToStr(False, True); //Zwraca napis "False"
end;
Data
Metod do wyświetlania, przechowywania, edytowania etc. dat jest tyle (7 stron, heh), że nie będę ich tu przepisywał i wymienię tylko kilka. Wszystkie są dostępne w module [[Delphi/Moduły/DateUtils]].StrToDate
Te funkcja służy do konwertowania właśnie daty na tekst.Funkcja Date zwraca aktualną datę.
begin
ShowMessage(DateToStr(Data));
end;
Odpowiednikiem zmieniający tekst na datę jest StrToDate.
StrToTime
Z kolei ta, jak się nie trudno domyśleć konwertuje czas na tekst.Funkcja Time zwraca aktualny czas.
begin
ShowMessage(TimeToStr(Time));
end;
Odpowiednikiem jest StrToTime.
Spoko arcik, tylko ostatni przyklad niejest zaabardzo dopracowany, alemtakto spoko
Poważny błąd w ostatnim pzykładzie ponieważ kopiuje kawałek adresu od początku do małpy a po małpie już nie potrzeba by jeszcze 1 pętelkę która by szła po małpie aż napotka spacje
No dobra, wszystko fajnie, ale jak np. usunąć powtarzające się adresy www wpisywane do comboboxa (które są zapisywane w pliku) przy uruchomieniu stworzonego programu???? Jak to samo zrobić dla pustych wierszy w comboboxie, które nieraz się tworzą??? Jak coś to domp.arts@interia.pl DZIĘKI