program NormalizeWhitespace;
{$mode objfpc}{$H+}
uses
SysUtils; // CharInSet
{ ------------------------------------------------------------
NormalizeWhitespace
------------------------------------------------------------
Removes extra whitespace from a string:
- Trim leading whitespace
- Trim trailing whitespace
- Collapse multiple internal whitespace into a single space
The algorithm performs a single linear scan and writes into
a result string. This avoids repeated allocations and keeps
the logic simple and efficient.
------------------------------------------------------------ }
function NormalizeWhitespace(const S: string): string;
var
i, j: Integer;
InWS, Started: Boolean;
Ch: Char;
begin
SetLength(Result, Length(S)); { Preallocate for efficiency }
j := 0;
InWS := False;
Started := False;
for i := 1 to Length(S) do
begin
Ch := S[i];
if CharInSet(Ch, [' ', #9, #10, #13]) then
begin
{ Skip leading whitespace }
if not Started then
Continue;
{ Skip repeated whitespace }
if InWS then
Continue;
{ First whitespace after a word → write a single space }
Inc(j);
Result[j] := ' ';
InWS := True;
end
else
begin
{ Non-whitespace character }
Inc(j);
Result[j] := Ch;
InWS := False;
Started := True;
end;
end;
{ Remove trailing space if present }
if (j > 0) and (Result[j] = ' ') then
Dec(j);
SetLength(Result, j);
end;
{ ------------------------------------------------------------
Main program
------------------------------------------------------------ }
var
S, Cleaned: string;
begin
S := ' This is a test string with extra spaces. ';
Cleaned := NormalizeWhitespace(S);
WriteLn('Original: [', S, ']');
WriteLn('Cleaned: [', Cleaned, ']');
end.
(*
run:
Original: [ This is a test string with extra spaces. ]
Cleaned: [This is a test string with extra spaces.]
*)