How to split string by a multi-character delimiter?

Is there a Delphi function to split string by a multi-character delimiter rather than a single character ?

For instance when I'd use that function this way:

SplitString('Whale<->Mammal<->Ocean', '<->')

I would get a result of these 3 strings:

'Whale', 'Mammal', 'Ocean'

Is there such function in Delphi for this ?


Solution 1:

There is another quite simple solution using TStringList. Change the LineBreak:

procedure TForm208.Button1Click(Sender: TObject);
var
  lst: TStringList;
begin
  lst := TStringList.Create;
  try
    lst.LineBreak := '<->';
    lst.Text := 'Whale<->Mammal<->Ocean';
    Memo1.Lines := lst;
  finally
    lst.Free;
  end;
end;

Solution 2:

You can check my StringUtils.pas unit that is part of Cromis Library

There is a simple text tokenizer there. But probably is just what you need. The interface is like that

TTextTokenizer = class
  private
    FTokens: TTokens;
    FDelimiters: array of ustring;
  public
    constructor Create;
    procedure Tokenize(const Text: ustring);
    procedure AddDelimiters(const Delimiters: array of ustring);
    property Tokens: TTokens read FTokens;
  end;

Suports strings as delimiters and also more then one delimiter.

Solution 3:

If you have JCL installed then in the jclStrings unit there is StrToStrings procedure:

var sl: TStringList;
begin
  sl := TStringList.Create;
  StrToStrings('Whale<->Mammal<->Ocean' , '<->' , sl);

Solution 4:

I don't know if Delphi has a standart split procedure that uses a string as a delimiter. But you can write your own either it has or not:

procedure SplitStr(const Source, Delimiter: String; var DelimitedList: TStringList);
var
  s: PChar;

  DelimiterIndex: Integer;
  Item: String;
begin
  s:=PChar(Source);

  repeat
    DelimiterIndex:=Pos(Delimiter, s);
    if DelimiterIndex=0 then Break;

    Item:=Copy(s, 1, DelimiterIndex-1);

    DelimitedList.Add(Item);

    inc(s, DelimiterIndex + Length(Delimiter)-1);
  until DelimiterIndex = 0;
  DelimitedList.Add(s);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  sl: TStringList;
begin
  sl:=TStringList.Create;
  SplitStr('delphi++split++string++','++',sl);
  //do something with the list
  sl.Free;
end;

Hope it helps..

Solution 5:

There is no such function 'from box'. If your strings contain regular 'good' text, then you can use StringReplace with exotic symbol, otherwise it is not hard to write own split function using Pos or IdStrings.SplitString (if it is available in D2010)

function SplitStringByStr(const S, StrDelimiter: string): TStringDynArray;
var
  tmp: string;
begin
  tmp := StringReplace(S, StrDelimiter, '`', [rfReplaceAll]);
  Result := SplitString(tmp, '`');
end;