7

I just need to split a string like: "STANS", "Payment, chk#1", ,1210.000 into an array based on ,. The result in the string list would be

STANS  
Payment, chk#1  

1210.000
Andriy M
  • 76,112
  • 17
  • 94
  • 154
suresh
  • 71
  • 1
  • 1
  • 3
  • This is not an answer but i can't make a comment yet... How can i do the same but instead for "," have ";"... Thank you – azrael11 Jun 10 '11 at 06:49

2 Answers2

12

Create a TStringList and assign your comma separated string to StringList.CommaText. This parses your input and returns the split strings as the items of the string list.

StringList.CommaText := '"STANS", "Payment, chk# 1", ,1210.000';
//StringList[0]='STANS'
//StringList[1]='Payment, chk# 1'
//etc.
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • If it doesn't work quite right, there are also improved versions out on the net. – mj2008 Jun 10 '11 at 08:43
  • 1
    @mj2008 Could you elaborate please? This code works fine on the example given. If you are going to debunk an answer it is better to provide some evidence. If you have evidence then I will very happily stand corrected. – David Heffernan Jun 10 '11 at 08:52
  • 1
    I upvoted you, and think it is the correct answer. I wasn't out to "debunk" you! I have a TStringCSVList from Magenta Systems that does some space improvements, but it is from 2000 so maybe the current Delphi implementation is better. For good CSV, Delphi is fine out of the box. For dodgy CSV, there are similar things out there. – mj2008 Jun 10 '11 at 09:08
  • @"David Heffernan" If the string contains spaces between the commas, but no double quotes, how would you go about this? For example, I have "900 024000649314,2015/07/04,08:23:12" as the first part of my line. If I do the following: ShowMessage(StringList[0]); It outputs only 900. Thanks in advance! – DearVolt Jul 13 '15 at 08:00
  • @DJSquared Set `StrictDelimiter` to `True`. – David Heffernan Jul 13 '15 at 08:05
  • Delphi 7 doesn't support the above mentioned, so I'm going to use on of the tricks mentioned on this thread: http://stackoverflow.com/questions/1335027/delphi-stringlist-delimiter-is-always-a-space-character-even-if-delimiter-is-se Thank you! – DearVolt Jul 13 '15 at 08:21
  • @DJSquared If I were you I would use a bespoke split function. How about my one from here: http://stackoverflow.com/questions/28410901/string-split-works-strange-when-last-value-is-empty/28411658#28411658 – David Heffernan Jul 13 '15 at 08:24
2

I wrote this function and works perfect for me in Delphi 2007

function ParseCSV(const S: string; ADelimiter: Char = ','; AQuoteChar: Char = '"'): TStrings;
type
  TState = (sNone, sBegin, sEnd);
var
  I: Integer;
  state: TState;
  token: string;

    procedure AddToResult;
    begin
      if (token <> '') and (token[1] = AQuoteChar) then
      begin
        Delete(token, 1, 1);
        Delete(token, Length(token), 1);
      end;
      Result.Add(token);
      token := '';
    end;

begin
  Result := TstringList.Create;
  state := sNone;
  token := '';
  I := 1;
  while I <= Length(S) do
  begin
    case state of
      sNone:
        begin
          if S[I] = ADelimiter then
          begin
            token := '';
            AddToResult;
            Inc(I);
            Continue;
          end;

          state := sBegin;
        end;
      sBegin:
        begin
          if S[I] = ADelimiter then
            if (token <> '') and (token[1] <> AQuoteChar) then
            begin
              state := sEnd;
              Continue;
            end;

          if S[I] = AQuoteChar then
            if (I = Length(S)) or (S[I + 1] = ADelimiter) then
              state := sEnd;
        end;
      sEnd:
        begin
          state := sNone;
          AddToResult;
          Inc(I);
          Continue;
        end;
    end;
    token := token + S[I];
    Inc(I);
  end;
  if token <> '' then
    AddToResult;
  if S[Length(S)] = ADelimiter then
    AddToResult
end;
FLICKER
  • 6,439
  • 4
  • 45
  • 75