views:

2828

answers:

2

I am having trouble with the delimiter in the TStringList Class. Take a look:

var
  s: string;
  sl: TStringList;

begin
  sl := TStringList.Create;
  s := 'Users^foo bar^bar foo^foobar^barfoo';
  sl.Delimiter := '^';
  sl.DelimitedText := s;
  ShowMessage(sl[1]);
end;

sl[1] SHOULD return 'foo bar'

sl[1] DOES return 'foo'

It seems that the delimiter is now '^' AND ' '

Any ideas?

+17  A: 

You should set s1.StrictDelimiter := True for spaces not to be considered delimiters, more info here.

Since you work in a version that does not support the above (as was clarified after the answer was submitted), you have two options:

  1. Find a character you know will not be used in the original text (e.g. underscore), convert all spaces to that character before splitting, and convert back after splitting. This is robosoft's suggestion.
  2. If you don't have inverted commas and spaces in the text, you can use Alexander's trick and wrap the text between delimiters in inverted command, so that 'hello hello^bye bye' turns to '"hello hello"^"bye bye"'. If you do choose this path and it works for you, please accept Alexander's answer and not mine, he also provides the code to implement it.

Both workarounds not using StrictDelimiter have limitations: the first requires some unused character, and the second requires no inverted commas and spaces in the original text.

Maybe it's time to upgrade to a newer version of Delphi :)

Roee Adler
Bummer! Any workaround starting point?
Acron
What do you want to work around? Looks like a solution to me.
Smasher
I do have Delphi 7, so this does not work for me.
Acron
Your starting point would be to read the source code for SetDelimitedText in Classes.pas, and either subclass TStrings to create a version that handles this the way you need, or just write a stand-alone function to split the string on carets and return a string list.
Todd
Could you temporarily turn spaces into something else, then change them back afterwards? Any other character that wouldn't normally appear in your list would work. It's a hack, or as we prefer 'necessary evil as a workaround'. :-)
robsoft
@Todd - That was the first significant sub-class I ever wrote in Delphi 3!
Gerry
+7  A: 
sl.DelimitedText := '"' + StringReplace(S, sl.Delimiter, '"' + sl.Delimiter + '"', [rfReplaceAll]) + '"';
Alexander
Crap, you beat me, I was typing exactly the same answer :)
The_Fox
Very clever, thank you Alexander, aswell as The_Fox, even if you diddn't help me directly, but you intended to do so :)
Acron
+1 Very nice, but has a problem if the original string contains a subsection like ' " " ' (i.e. inverted commas and spaces in the text)
Roee Adler
>>> has a problem if the original string contains a subsection like ' " " 'And how can user name contain '"' char? :)
Alexander
@Alexander - Here's an example: 'Bill "The Womanizer" Clinton' :)
Roee Adler