【问题标题】:How to split string by a multi-character delimiter?如何通过多字符分隔符拆分字符串?
【发布时间】:2013-03-03 16:31:42
【问题描述】:

是否有 Delphi 函数通过多字符分隔符而不是单个字符来分割字符串?

例如,当我以这种方式使用该功能时:

SplitString('Whale<->Mammal<->Ocean', '<->')

我会得到这 3 个字符串的结果:

'Whale', 'Mammal', 'Ocean'

Delphi 有这个功能吗?

【问题讨论】:

标签: delphi delphi-2010


【解决方案1】:

我不知道 Delphi 是否有一个使用字符串作为分隔符的标准拆分过程。但是你可以自己写,不管有没有:

procedure SplitStr(const Source, Delimiter: String; var DelimitedList: TStringList);
var
  s: PChar;

  DelimiterIndex: Integer;
  Item: String;
begin
  s:=PChar(Source);

  repeat
    DelimiterIndex:=Pos(Delimiter, s);
    if DelimiterIndex=0 then Break;

    Item:=Copy(s, 1, DelimiterIndex-1);

    DelimitedList.Add(Item);

    inc(s, DelimiterIndex + Length(Delimiter)-1);
  until DelimiterIndex = 0;
  DelimitedList.Add(s);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  sl: TStringList;
begin
  sl:=TStringList.Create;
  SplitStr('delphi++split++string++','++',sl);
  //do something with the list
  sl.Free;
end;

希望对你有帮助..

【讨论】:

    【解决方案2】:

    没有'from box'这样的功能。如果您的字符串包含常规的“好”文本,那么您可以使用带有奇异符号的 StringReplace,否则使用 Pos 或 IdStrings.SplitString 编写自己的拆分函数并不难(如果它在 D2010 中可用)

    function SplitStringByStr(const S, StrDelimiter: string): TStringDynArray;
    var
      tmp: string;
    begin
      tmp := StringReplace(S, StrDelimiter, '`', [rfReplaceAll]);
      Result := SplitString(tmp, '`');
    end;
    

    【讨论】:

    • 我能看到的唯一问题是如果文本包含“异国符号”,这种方法将不起作用(正如你所指出的)。
    • 您通常可以在 ASCII 的不可打印部分的某处找到未在字符串中使用的“奇异符号”,例如 #13(回车)或 #8(铃)。
    【解决方案3】:

    您可以检查我的 StringUtils.pas 单元,它是 Cromis Library 的一部分

    那里有一个简单的文本标记器。但可能正是您所需要的。界面是这样的

    TTextTokenizer = class
      private
        FTokens: TTokens;
        FDelimiters: array of ustring;
      public
        constructor Create;
        procedure Tokenize(const Text: ustring);
        procedure AddDelimiters(const Delimiters: array of ustring);
        property Tokens: TTokens read FTokens;
      end;
    

    支持字符串作为分隔符,也支持多个分隔符。

    【讨论】:

    • 我以前没有听说过 Cromis。 Cromis 有单元测试吗?我在下载 zip 中找不到任何内容。另外,最好在线浏览代码,或者至少一些 API 文档(只是一个建议)
    • 它是我在很多生产代码中使用的库,如果他们愿意,可以分享给其他人。我仍然需要通过测试覆盖一些单元。对于大多数主要作品,我都有涵盖大部分功能的演示程序。我将扩大测试覆盖率并将 SVN 公开。但是文档可能会很晚,因为这些天我没有太多时间。其中一些组件被很多人使用,尤其是 IPC 和 Scheduler。
    • 相信您在另一个答案中发布的来源,它只会在分隔符上标记一次,也不会以任何随机顺序对所有分隔符进行标记。
    【解决方案4】:

    还有另一个使用 TStringList 的非常简单的解决方案。更改换行符:

    procedure TForm208.Button1Click(Sender: TObject);
    var
      lst: TStringList;
    begin
      lst := TStringList.Create;
      try
        lst.LineBreak := '<->';
        lst.Text := 'Whale<->Mammal<->Ocean';
        Memo1.Lines := lst;
      finally
        lst.Free;
      end;
    end;
    

    【讨论】:

    • 你应该使用'StrictDelimiter'吗?还是在这种情况下没关系?
    • @awmross,因为我们在这里不使用 DelimitedText,所以 StrictDelimiter 的状态根本不重要。
    【解决方案5】:

    如果您安装了JCL,那么在jclStrings 单元中有StrToStrings 过程:

    var sl: TStringList;
    begin
      sl := TStringList.Create;
      StrToStrings('Whale<->Mammal<->Ocean' , '<->' , sl);
    

    【讨论】:

      【解决方案6】:

      较新版本的 Delphi 有一个 stringhelper 可以做到这一点:

      var
        lStr: string;
        lSplitStr: TArray<string>;
      begin
        lStr := 'Whale<->Mammal<->Ocean';
        lSplitStr := lStr.Split('<->');
      end;
      

      现在 lSplitStr 是一个包含 3 个元素的数组:“鲸鱼”、“哺乳动物”、“海洋”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-30
        • 2010-11-10
        • 2014-03-02
        • 2017-03-21
        • 1970-01-01
        • 2010-11-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多