I need to parse strings out of a TStringStream using a substring delimiter in Delphi?

delphi, delphi-xe, stream, stringstream, substring

Solution

Since you are already using Indy, you can use its `SplitColumnsNoTrim()` function to split a `String` into a `TStrings` using a delimiter String that can contain multiple characters in it. As it name suggests, `SplitColumnsNoTrim()` does not apply any trimming between the separated substrings. If you want trimming, use `SplitColumns()` instead.

var
  Strm: TStringStream;
  Strings: TStringList;
begin
  Strings := TStringList.Create;
  try
    Strm := TStringStream.Create;
    try
      IdHTTP.Get('http://...', Strm);
      SplitColumnsNoTrim(Strm.DataString, Strings, '[eol]'); 
    finally
      Strm.Free;
    end;
    // use Strings as needed ...
  finally
    Strings.Free;
  end;
end;

I would not advise using a `TStringStream` for this kind of parsing, though. `TStringStream` in D2009+ requires you to specify a `TEncoding` in its constructor (or let it default to the OS default Ansi encoding), which you cannot do if you have `TIdHTTP` download directly into the `TStringStream`. You won't know the charset of the data ahead of time, unless the data is always ASCII. `TIdHTTP` has logic to decode the downloaded data into a `String` using the data's actual charset, so you should utilize that functionality instead, eg:

var
  Strings: TStringList;
begin
  Strings := TStringList.Create;
  try
    SplitColumnsNoTrim(IdHTTP.Get('http://...'), Strings, '[eol]'); 
    // use Strings as needed ...
  finally
    Strings.Free;
  end;
end;

Problem

Using Delphi XE, I need to parse a TStringStream into strings delimited by a String. The delimiter-string in one case would be [eol]. The stream is loaded from a webserver using indy IdHttp. I then need to parse the strings out of the Stream, and they are separated by the string "[eol]". As an example the StringStream could contain: "12345[eol]this is] something[eol]and [this is nothing[eol]etc[etcetc[[eol]" should parse into: "12345" "this is] something" "and [this is nothing" "etc[etcetc[" Most delimiter techniques I know use only single character delimiters, and then I also need to iterate through the entire Stream until its end. I'm at a loss, Regards Adrian

Original source