Recent

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

CM630

  • Hero Member
  • *****
  • Posts: 1146
  • Не съм сигурен, че те разбирам.
    • 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 »
Лазар 3,4 32 bit (sometimes 64 bit); FPC3,2,2

Thaddy

  • Hero Member
  • *****
  • Posts: 15131
  • Censorship about opinions does not belong here.
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 »
Of course the national anthem of the U.S.A. was written by Jimi Hendrix, didn't you know that?

CM630

  • Hero Member
  • *****
  • Posts: 1146
  • Не съм сигурен, че те разбирам.
    • 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?
Лазар 3,4 32 bit (sometimes 64 bit); FPC3,2,2

wp

  • Hero Member
  • *****
  • Posts: 12122
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: 1146
  • Не съм сигурен, че те разбирам.
    • 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.
Лазар 3,4 32 bit (sometimes 64 bit); FPC3,2,2

Thaddy

  • Hero Member
  • *****
  • Posts: 15131
  • Censorship about opinions does not belong here.
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
Of course the national anthem of the U.S.A. was written by Jimi Hendrix, didn't you know that?

CM630

  • Hero Member
  • *****
  • Posts: 1146
  • Не съм сигурен, че те разбирам.
    • 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;      
Лазар 3,4 32 bit (sometimes 64 bit); FPC3,2,2

wp

  • Hero Member
  • *****
  • Posts: 12122
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: 1146
  • Не съм сигурен, че те разбирам.
    • 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!
Лазар 3,4 32 bit (sometimes 64 bit); FPC3,2,2

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4498
  • 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: 1146
  • Не съм сигурен, че те разбирам.
    • 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.
Лазар 3,4 32 bit (sometimes 64 bit); FPC3,2,2

creaothceann

  • Full Member
  • ***
  • Posts: 117

Thaddy

  • Hero Member
  • *****
  • Posts: 15131
  • Censorship about opinions does not belong here.
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.
Of course the national anthem of the U.S.A. was written by Jimi Hendrix, didn't you know that?

ASerge

  • Hero Member
  • *****
  • Posts: 2287
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: 93
  • 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