18
votes

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 ?

6
To all you close voters: please read both questions. This is patently not a dupe of stackoverflow.com/questions/2625707/…David Heffernan

6 Answers

41
votes

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

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.

5
votes

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);
4
votes

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..

3
votes

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

Newer versions of Delphi has a stringhelper that does this:

var
  lStr: string;
  lSplitStr: TArray<string>;
begin
  lStr := 'Whale<->Mammal<->Ocean';
  lSplitStr := lStr.Split('<->');
end;

Now lSplitStr is an array with the 3 elements: 'Whale', 'Mammal', 'Ocean'.