Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to split a string in Inno Setup

How can I split a string in Inno Setup?
Is there any special function in Inno Setup to split the string?

I want to get the following from the string '11.2.0.16':

tokens: array of string = ('11', '0', '2', '16');

Thanks in advance!

like image 283
srikanth1267 Avatar asked May 23 '14 19:05

srikanth1267


4 Answers

For anyone who prefers the function format, I have modified @cezarlamann's answer:

function StrSplit(Text: String; Separator: String): TArrayOfString;
var
  i, p: Integer;
  Dest: TArrayOfString; 
begin
  i := 0;
  repeat
    SetArrayLength(Dest, i+1);
    p := Pos(Separator,Text);
    if p > 0 then begin
      Dest[i] := Copy(Text, 1, p-1);
      Text := Copy(Text, p + Length(Separator), Length(Text));
      i := i + 1;
    end else begin
      Dest[i] := Text;
      Text := '';
    end;
  until Length(Text)=0;
  Result := Dest
end;
like image 199
timyhac Avatar answered Nov 20 '22 06:11

timyhac


I've been looking for the same thing today...

This one works just fine on Inno Setup Scripts. Paste this excerpt inside your script before the procedure/function which will call this "split" procedure.

You can also modify this onto a function, if you desire...

procedure Explode(var Dest: TArrayOfString; Text: String; Separator: String);
var
  i, p: Integer;
begin
  i := 0;
  repeat
    SetArrayLength(Dest, i+1);
    p := Pos(Separator,Text);
    if p > 0 then begin
      Dest[i] := Copy(Text, 1, p-1);
      Text := Copy(Text, p + Length(Separator), Length(Text));
      i := i + 1;
    end else begin
      Dest[i] := Text;
      Text := '';
    end;
  until Length(Text)=0;
end;

procedure Whatever();
var 
  str: String;
  strArray: TArrayOfString;
  i: Integer;
begin
  Explode(strArray,str,'.');
  for i:=0 to GetArrayLength(strArray)-1 do begin
    { do something }
  end;
end;

Taken from here

like image 35
cezarlamann Avatar answered Nov 20 '22 05:11

cezarlamann


Here's what I use:

procedure SplitString(S, Delim: string; var Dest: TArrayOfString);
var
  Temp: string;
  I, P: Integer;
begin
  Temp := S;
  I := StringChangeEx(Temp, Delim, '', true);
  SetArrayLength(Dest, I + 1);
  for I := 0 to GetArrayLength(Dest) - 1 do
  begin
    P := Pos(Delim, S);
    if P > 0 then
    begin
      Dest[I] := Copy(S, 1, P - 1);
      Delete(S, 1, P + Length(Delim) - 1);
    end
    else
      Dest[I] := S;
  end;
end;

This version avoids repeated array resizing by counting the delimiters using StringChangeEx and setting the array size only once. Since we then know the array size, we can just use a for loop. I also opted for Delete rather than Copy, which (IMO) makes the code easier to read. (This version also fixes the bug where the split does not occur correctly if the delimiter is longer than 1 character.)

like image 21
Bill_Stewart Avatar answered Nov 20 '22 05:11

Bill_Stewart


If there is a possibility that the delimiter could also be right at the end of the string, then this is what I used (modified from @timyha's answer)

function StrSplit(Text: String; Separator: String): TArrayOfString;
var
  i, p: Integer;
  Dest: TArrayOfString; 
begin
  i := 0;
  repeat
    SetArrayLength(Dest, i+1);
    p := Pos(Separator,Text);

    if p > 0 then begin
      Dest[i] := Copy(Text, 1, p-1);
      Text := Copy(Text, p + Length(Separator), Length(Text));
      i := i + 1;
      
      //add an empty string if delim was at the end 
         
      if Text = '' then begin
        Dest[i]:=''; 
        i := i + 1;
      end;

    end else begin
      Dest[i] := Text;
      Text := '';
    end;
  until Length(Text)=0;
  Result := Dest
end;
like image 1
S. Francis Avatar answered Nov 20 '22 05:11

S. Francis