如何在Inno Setup中拆分字符串

12

如何在Inno Setup中拆分字符串?
Inno Setup中是否有特殊的函数可用于拆分字符串?

我想从字符串'11.2.0.16'中获取以下内容:

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

提前感谢!

4个回答

20

对于那些更喜欢函数格式的人,我修改了 @cezarlamann的答案:

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;

13

今天我一直在寻找同样的东西......

这个对Inno Setup脚本完美地起作用。将这段摘录粘贴到您的脚本中,在调用此“split”过程的过程/函数之前。

如果您需要,您还可以将其修改为一个函数......

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;

来源于这里


只是出于好奇,这里有一个棘手的替代方案,它将所有分隔符字符替换为换行符,并将这样的文本加载到字符串列表中,该列表会自动将值分解为项。但无论如何,这还不是全部。您需要从原始字符串中剥离要解析的子字符串,最后从值中删除引号并将这些值格式化为点分字符串(因此我最初评论了“split”)。 - TLama

3

这是我使用的内容:

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;

这个版本通过使用StringChangeEx计算分隔符的数量并仅设置一次数组大小,避免了重复的数组调整大小。由于我们知道数组的大小,因此我们可以只使用 for 循环。我选择使用Delete而不是Copy,这使得代码更易读(在这个版本中还修复了当分隔符长度大于1时拆分不正确的错误)。


1
如果分隔符有可能出现在字符串的末尾,那么这是我使用的代码(修改自@timyha的答案)。
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;

1
一个小笔误:在 if Text = '' ... 行后应该是 Dest[i] := ''。你漏了冒号。否则这个对我来说很好用。 - RexBarker
谢谢。已更正错别字。 - S. Francis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接