20

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 ?

TLama
  • 75,147
  • 17
  • 214
  • 392
awmross
  • 3,789
  • 3
  • 38
  • 51
  • 3
    To all you close voters: please read both questions. This is patently not a dupe of http://stackoverflow.com/questions/2625707/split-a-string-into-an-array-of-strings-based-on-a-delimiter – David Heffernan Mar 15 '13 at 11:43

6 Answers6

43

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;
Uwe Raabe
  • 45,288
  • 3
  • 82
  • 130
7

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.

Runner
  • 6,073
  • 26
  • 38
  • I had not heard of Cromis before. Does Cromis have any unit tests? I couldn't find any in the download zip. Also, it would be good to browse the code online, or at least some API documentation (just a suggestion) – awmross Mar 15 '13 at 16:47
  • 1
    Its a library I use in a lot of production code and share it for others if they wish. I still have to cover some units with tests. For most major pieces I have demo programs that cover most of the functionality. I will extend test coverage and make the SVN public. But documentation will probably be very late as I don't have much time these days. Some of the components are quite used by a lot of people, especially IPC and Scheduler. – Runner Mar 15 '13 at 18:33
  • trusting to the sources you posted in another Answer, it only tokenizes once for every on the delimiters, nor upon all of them in any random order they are met. – Arioch 'The Jan 13 '16 at 16:44
6

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);
ain
  • 22,394
  • 3
  • 54
  • 74
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..

Hasan Manzak
  • 663
  • 6
  • 14
3

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;
MBo
  • 77,366
  • 5
  • 53
  • 86
  • The only problem I can see with that is if the text contains the 'exotic symbol', this method will not work (as you pointed out). – awmross Mar 15 '13 at 04:33
  • 2
    You can usually find an 'exotic symbol' that is not used in strings somewhere in the unprintable parts of the ASCII, for example #13 (carriage return) or #8 (bell). – gabr Mar 15 '13 at 07:37
2

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

Xel Naga
  • 826
  • 11
  • 28
Hans
  • 2,220
  • 13
  • 33