Welcome to collectivesolver - Programming & Software Q&A with code examples. A website with trusted programming answers. All programs are tested and work.

Contact: aviboots(AT)netvision.net.il

Semrush - keyword research tool

Create your online store today with Shopify

Turn ChatGPT, Claude, Gemini, And CoPilot Into Your Personal Assistant, Business Coach, Content Creator, And More

AFFILIATE MARKETING Your all-in-one performance engine Manage affiliates, creators, and customer referrals in one unified platform—turning every partnership into measurable growth

Secure & Reliable Web Hosting, Free Domain, Free SSL, 1-Click WordPress Install, Expert 24/7 Support

Disclosure: My content contains affiliate links.

43,226 questions

56,128 answers

573 users

How to remove duplicate case‑insensitive words separated by multiple delimiters from a string in Pascal

1 Answer

0 votes
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

}

 



answered Aug 1 by avibootz

Related questions

...