Strings and Characters

8.1 String Basics

string = UnicodeString: UTF-16, reference counted, copy-on-write, 1-based indexing (by default on all platforms in modern versions).

var
  S: string;
begin
  S := 'Hello, Delphi';
  Writeln(Length(S));          // 13
  Writeln(S[1]);               // 'H' (1-based!)
  S[1] := 'J';                 // modifies (copy-on-write if shared)
  S := S + '!';
  Writeln(Copy(S, 8, 6));      // 'Delphi'
  Writeln(Pos('Del', S));      // 8 (0 if not found)
  Insert('Dear ', S, 8);
  Delete(S, 1, 7);
  SetLength(S, 5);
end;

8.2 String Functions (System.SysUtils, System.StrUtils)

UpperCase(S); LowerCase(S); Trim(S); TrimLeft(S); TrimRight(S);
IntToStr(42); StrToInt('42'); StrToIntDef('x', 0); TryStrToInt('42', N);
FloatToStr(3.14); StrToFloat('3.14'); FormatFloat('#,##0.00', 1234.5);
Format('%s is %d years old and has %.2f', ['Ana', 30, 99.5]);
StringReplace(S, 'old', 'new', [rfReplaceAll, rfIgnoreCase]);
SameText('abc', 'ABC');         // case-insensitive compare
CompareStr(A, B); CompareText(A, B);
QuotedStr('it''s');             // 'it''s'
StringOfChar('*', 10); DupeString('ab', 3);
LeftStr(S, 3); RightStr(S, 3); MidStr(S, 2, 3);
ContainsText(S, 'del'); StartsText('He', S); EndsText('hi', S);
ReverseString(S); IfThen(Cond, 'yes', 'no');
SplitString('a,b,c', ',');      // TStringDynArray

8.3 String Helper Methods (TStringHelper)

⚠️ Classic functions (Pos, Copy, S[i]) are 1-based. TStringHelper methods (IndexOf, Substring, Chars[]) are 0-based.

var S := '  Hello World  ';
S.Trim; S.ToUpper; S.ToLower; S.Length; S.Contains('World');
S.StartsWith('  He'); S.EndsWith('  '); S.IndexOf('o');   // IndexOf is 0-based!
S.Replace('World', 'Delphi'); S.Substring(2, 5);          // Substring is 0-based!
S.Split([' '], TStringSplitOptions.ExcludeEmpty);
S.PadLeft(20, '.'); S.IsEmpty; string.IsNullOrWhiteSpace(S);
string.Join(', ', ['a', 'b', 'c']);
S.ToInteger; S.ToDouble; 42.ToString; 3.14.ToString;

8.4 TStringBuilder and TStringList

var SB := TStringBuilder.Create;
try
  for var I := 1 to 5 do
    SB.Append('Line ').Append(I).AppendLine;
  Writeln(SB.ToString);
finally
  SB.Free;
end;

var List := TStringList.Create;
try
  List.Add('banana');
  List.Add('apple');
  List.Sort;
  List.Values['color'] := 'red';                 // name=value pairs
  List.Delimiter := ',';
  List.StrictDelimiter := True;
  List.DelimitedText := 'x,y,z';
  List.LoadFromFile('data.txt', TEncoding.UTF8);
  List.SaveToFile('out.txt');
  Writeln(List.Text, List.Count, List.IndexOf('apple'));
  List.Duplicates := dupIgnore; List.Sorted := True;
  List.CaseSensitive := False;
finally
  List.Free;
end;

8.5 Encodings and Other String Types

var Bytes := TEncoding.UTF8.GetBytes('héllo');
var Back := TEncoding.UTF8.GetString(Bytes);
var Utf8: UTF8String := 'text';                  // for C APIs / files
var Ansi: AnsiString := 'legacy';                // codepage-dependent
var P: PChar := PChar(S);                        // pointer to null-terminated chars (Windows APIs)

8.6 Characters and Regular Expressions

uses System.Character, System.RegularExpressions;

Writeln(IsDigit('5'), Char('a').IsLetter, 'a'.ToUpper, Ord('A'), Chr(66));

if TRegEx.IsMatch(Email, '^[\w.+-]+@[\w-]+\.[\w.]+$') then Writeln('valid');
var M := TRegEx.Match('Order 12345 shipped', '\d+');
if M.Success then Writeln(M.Value);
for var Match in TRegEx.Matches('a1b22c333', '\d+') do Writeln(Match.Value);
Writeln(TRegEx.Replace('Phone: 98-765-43210', '\D', ''));
var D := TRegEx.Match('2025-10-24', '(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})');
Writeln(D.Groups['y'].Value);