Recent

Author Topic: [Solved]String delimiter for TStringList?  (Read 10147 times)

CM630

  • Hero Member
  • *****
  • Posts: 1022
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
[Solved]String delimiter for TStringList?
« on: September 28, 2018, 10:02:20 am »
I have tried to use TStringList, but because it accepts only characters but not strings for delimiters, it occurs to be quite useless.
Is there a way to make it use a string for a delimeter? Or maybe there is another component which would do the job?
« Last Edit: October 01, 2018, 08:53:58 am by CM630 »
Лазар 2,2,4 32 bit; FPC3,2,2; rev: Lazarus_2_2_4 on W10 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 12974
Re: String delimiter for TStringList?
« Reply #1 on: September 28, 2018, 11:27:51 am »
Tstringlist.text.split? Has several overrides. Does what you mean. But only for Ansi strings.
« Last Edit: September 28, 2018, 11:29:56 am by Thaddy »
I actually get compliments for being rude... (well, Dutch, but that is the same)

CM630

  • Hero Member
  • *****
  • Posts: 1022
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: String delimiter for TStringList?
« Reply #2 on: September 28, 2018, 11:38:10 am »
Thanks and please excuse me for the small font.
1. I need to convert a delimted string to a tStringList.
   stNCRConstList.Text.Split('\n',MyString); generates and error.
2. I need to convert a tStringList to a delimited string.
   MyString := stNCRConstList.Text.Join('\n',stNCRConstList.Text); compiles, but it seems pretty odd that I need a second parameter. I have not tried how it works.


Maybe logic of Split and Join is inverted?
Лазар 2,2,4 32 bit; FPC3,2,2; rev: Lazarus_2_2_4 on W10 64bit.

wp

  • Hero Member
  • *****
  • Posts: 10858
Re: String delimiter for TStringList?
« Reply #3 on: September 28, 2018, 11:51:48 am »
Everbody seems to think in terms of these helpers all the time and forgets about plain old Pascal code:
Code: Pascal  [Select][+][-]
  1.   stNCRConstList.Text := StringReplace(MyString, '\n', Lineending, [rfReplaceAll, rfIgnoreCase]);

CM630

  • Hero Member
  • *****
  • Posts: 1022
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: String delimiter for TStringList?
« Reply #4 on: September 28, 2018, 11:53:48 am »
I was thinking about that but that solution seems somehow... wrong to me.
Лазар 2,2,4 32 bit; FPC3,2,2; rev: Lazarus_2_2_4 on W10 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 12974
Re: String delimiter for TStringList?
« Reply #5 on: September 28, 2018, 12:01:37 pm »
Everbody seems to think in terms of these helpers all the time and forgets about plain old Pascal code:
Code: Pascal  [Select][+][-]
  1.   stNCRConstList.Text := StringReplace(MyString, '\n', Lineending, [rfReplaceAll, rfIgnoreCase]);
Feel free to write the whole book where an outline would suffice... :-X
I actually get compliments for being rude... (well, Dutch, but that is the same)

CM630

  • Hero Member
  • *****
  • Posts: 1022
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: String delimiter for TStringList?
« Reply #6 on: September 28, 2018, 01:45:57 pm »

Oops, I was actually thinking about
Code: Pascal  [Select][+][-]
  1.    stNCRConstList.Delimiter:=#13;
  2.    stNCRConstList.DelimitedText:=StringReplace(MyString, '\n', #13, [rfReplaceAll, rfIgnoreCase])
  3.  

I would have never guessed that your
    stNCRConstList.Text := StringReplace(MyString, '\n', Lineending, [rfReplaceAll, rfIgnoreCase]);
should work.

But for some reason it does as long as default value of stNCRConstList.Delimiter is kept (whatever it is).

Code: Pascal  [Select][+][-]
  1. //This works
  2.  
  3. procedure TForm1.Button1Click(Sender: TObject);
  4. var
  5.     stNCRConstList: TStringList=nil;
  6. begin
  7.      stNCRConstList:= TStringList.create;
  8.      stNCRConstList.text:=StringReplace('1\n2\n\3','\n',Lineending,[rfReplaceAll, rfIgnoreCase]);
  9.      ShowMessage(IntToStr(stNCRConstList.Count));
  10.      stNCRConstList.free;
  11. end;
  12.  
Code: Pascal  [Select][+][-]
  1. //This crashes
  2.  
  3. procedure TForm1.Button2Click(Sender: TObject);
  4. var
  5.     stNCRConstList: TStringList=nil;
  6. begin
  7.      stNCRConstList.Delimiter:='f';
  8.      stNCRConstList:= TStringList.create;
  9.      stNCRConstList.text:=StringReplace('1\n2\n\3','\n','f',[rfReplaceAll, rfIgnoreCase]);
  10.      ShowMessage(IntToStr(stNCRConstList.Count));
  11.      stNCRConstList.free;
  12. end;      
Лазар 2,2,4 32 bit; FPC3,2,2; rev: Lazarus_2_2_4 on W10 64bit.

wp

  • Hero Member
  • *****
  • Posts: 10858
Re: String delimiter for TStringList?
« Reply #7 on: September 28, 2018, 02:09:44 pm »
I think you should find some documentation of TStringList, TStrings etc (e.g. http://www.delphibasics.co.uk/RTL.asp?Name=tstringlist).

For short:
  • TStringList items are individual strings stored in a list. The property TStringList.Text combines all items to a single string in which the items are separated by LineEndings. That's why my example is working: replace the \n by LineEndings and assign this to the Text of the stringlist - then the stringlist splits the single string into indivudual items whenever it sees a LineEnding.
  • CommaText does the same, but it has a comma between the stringlist items.
  • DelimitedText is more flexible. Here you can define the character separating the items. If you say the Delimiter is 'f' then the Text is split wherever an 'f' is found. Your example does not work because you assign the StringReplace result to .Text, not to .DelimitedText.
    DelimitedText is a bit more complicated, though, because besides the Delimiter the text is also split at spaces and quotes. You can avoid this if you set StrictDelimiter to true.

CM630

  • Hero Member
  • *****
  • Posts: 1022
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: [SOLVED]String delimiter for TStringList?
« Reply #8 on: September 28, 2018, 03:17:44 pm »
Thanks, I will add this info to the Lazarus wiki!
Лазар 2,2,4 32 bit; FPC3,2,2; rev: Lazarus_2_2_4 on W10 64bit.

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4222
  • I like bugs.
Re: [SOLVED]String delimiter for TStringList?
« Reply #9 on: September 28, 2018, 03:33:56 pm »
Thanks, I will add this info to the Lazarus wiki!
Why exactly? TStringList is already well documented elsewhere.
If you have extra energy then please improve the wiki with information that cannot be found elsewhere.
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

CM630

  • Hero Member
  • *****
  • Posts: 1022
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: String delimiter for TStringList?
« Reply #10 on: September 28, 2018, 04:11:19 pm »
I have market as solved, but
Code: Pascal  [Select][+][-]
  1.  
  2. procedure TForm1.Button1Click(Sender: TObject);
  3. var
  4.     MyStringList: TStringList=nil;
  5. begin
  6.      MyStringList:= TStringList.create;
  7.      MyStringList.add('1');
  8.      MyStringList.add('2');
  9.      MyStringList.add('3');
  10.      ShowMessage(StringReplace(MyStringList.Text,Lineending,'\n', [rfReplaceAll, rfIgnoreCase]));
  11.      MyStringList.free;
  12. end;

resulted in '1\n2\n3\n'.
Last line ending needs to be removed. Not unsolvable, of course.
Лазар 2,2,4 32 bit; FPC3,2,2; rev: Lazarus_2_2_4 on W10 64bit.

creaothceann

  • Full Member
  • ***
  • Posts: 117

Thaddy

  • Hero Member
  • *****
  • Posts: 12974
Re: String delimiter for TStringList?
« Reply #12 on: September 28, 2018, 05:43:35 pm »
https://www.freepascal.org/docs-html/rtl/classes/tstrings.skiplastlinebreak.html
Indeed.
It must be frustrating to see how many people actually ignore the excellent documentation.
I actually get compliments for being rude... (well, Dutch, but that is the same)

ASerge

  • Hero Member
  • *****
  • Posts: 2066
Re: String delimiter for TStringList?
« Reply #13 on: September 29, 2018, 08:45:18 am »
Last line ending needs to be removed. Not unsolvable, of course.[/font][/font][/size]
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. {$MODE OBJFPC}
  3. {$LONGSTRINGS ON}
  4.  
  5. uses Classes, SysUtils;
  6.  
  7. function StringsToArray(L: TStrings): TStringArray;
  8. var
  9.   i: Integer;
  10. begin
  11.   SetLength(Result, L.Count);
  12.   for i := 0 to L.Count - 1 do
  13.     Result[i] := L[i];
  14. end;
  15.  
  16. var
  17.   L: TStringList;
  18.   S: string;
  19. begin
  20.   L := TStringList.Create;
  21.   try
  22.     L.Append('Line1');
  23.     L.Append('Line2');
  24.     L.Append('Line3');
  25.     for S in L do
  26.       Writeln(S);
  27.     Writeln;
  28.     S := ''.Join('(+)', StringsToArray(L));
  29.     Writeln(S);
  30.   finally
  31.     L.Free;
  32.   end;
  33.   Readln;
  34. end.

Almir.Bispo

  • Jr. Member
  • **
  • Posts: 91
  • CSV Comp DB is the Best NoSQL
    • CSV Comp DB (NoSQL)
Re: String delimiter for TStringList?
« Reply #14 on: September 29, 2018, 05:05:25 pm »
Code: Pascal  [Select][+][-]
  1.  
  2. procedure mybutton;
  3. var s:Tstringlist;
  4. begin
  5. s:=Tstringlist.create;
  6. s.delimiter := char(';'); //delimiter used
  7. s.text := 'A;B;C;D'; //fill text
  8.  
  9. s.delimitedText := s.Text;
  10. showmessage(s.text);
  11. s.free;
  12.  
  13. end;
  14.  
CSV Comp DB Developer {Pascal Lover}

 

TinyPortal © 2005-2018