program RemoveDuplicatesMultiDelimiterCI;
{$mode objfpc}{$H+}
{
Removes duplicate case‑insensitive words separated by multiple delimiters.
Fix applied:
- TStringList.Delimiter requires a Char, not a String.
- We now use a Char sentinel (#10) directly.
}
uses
SysUtils, Classes;
function TrimSpaces(const S: string): string;
begin
Result := Trim(S);
end;
function ToLower(const S: string): string;
begin
Result := LowerCase(S);
end;
function RemoveDuplicatesMultiDelimiterCI(
const Input: string;
const Delimiters: array of string;
const OutputDelimiter: string
): string;
var
Normalized: string;
Sentinel: Char; // <-- FIX: must be Char
D: string;
PosDel: SizeInt;
Tokens: TStringList;
Seen: TStringList;
Token, Key: string;
I: Integer;
begin
{ Step 1: Replace all delimiters with a single sentinel character }
Normalized := Input;
Sentinel := #10; { newline as safe sentinel }
for D in Delimiters do
begin
PosDel := Pos(D, Normalized);
while PosDel > 0 do
begin
Delete(Normalized, PosDel, Length(D));
Insert(Sentinel, Normalized, PosDel); // <-- Insert Char, not String
PosDel := Pos(D, Normalized);
end;
end;
{ Step 2: Split by sentinel }
Tokens := TStringList.Create;
Seen := TStringList.Create;
try
Tokens.Delimiter := Sentinel; // <-- FIX: now valid (Char)
Tokens.StrictDelimiter := True;
Tokens.DelimitedText := Normalized;
{ Step 3: Remove duplicates (case‑insensitive) }
Seen.Sorted := False;
Seen.Duplicates := dupIgnore;
Result := '';
for I := 0 to Tokens.Count - 1 do
begin
Token := TrimSpaces(Tokens[I]);
if Token = '' then Continue;
Key := ToLower(Token);
if Seen.IndexOf(Key) = -1 then
begin
Seen.Add(Key);
if Result <> '' then
Result := Result + OutputDelimiter;
Result := Result + Token;
end;
end;
finally
Tokens.Free;
Seen.Free;
end;
end;
var
S: string;
ResultStr: string;
begin
S := 'AAA | aaa , aAA * aaA | AAa | AAA | BBB | ccc ---- CCC | AAA ; aaa | bbb';
ResultStr := RemoveDuplicatesMultiDelimiterCI(
S,
[' ', '|', ',', '*', '-', ';'],
' | '
);
WriteLn(ResultStr);
end.
{
run:
AAA | BBB | ccc
}