Delphi:即使设置了 Delimiter,StringList Delimiter 也始终是空格字符

Posted

技术标签:

【中文标题】Delphi:即使设置了 Delimiter,StringList Delimiter 也始终是空格字符【英文标题】:Delphi: StringList Delimiter is always a space character even if Delimiter is set 【发布时间】:2010-11-23 00:44:06 【问题描述】:

我在使用 TStringList 类中的分隔符时遇到问题。看看:

var
  s: string;
  sl: TStringList;

begin
  sl := TStringList.Create;
  s := 'Users^foo bar^bar foo^foobar^barfoo';
  sl.Delimiter := '^';
  sl.DelimitedText := s;
  ShowMessage(sl[1]);
end;

sl[1] 应该返回 'foo bar'

sl[1] 确实返回 'foo'

现在看来分隔符是'^' AND ' '

有什么想法吗?

【问题讨论】:

您使用的是什么版本的 Delphi? Split a string into an array of strings based on a delimiter 的可能重复项 我从来没有像现在这样对语言错误更生气过。谢谢你,Acron,让我注意到这一点。 【参考方案1】:

Delphi 7 中的工作对我来说“就像手套一样”。这是我应用 Alexander's Trick 后的功能:

procedure Split (const Delimiter: Char; Input: string; const Strings: TStrings) ;
begin
   Assert(Assigned(Strings)) ;
   Strings.Clear;
   Strings.Delimiter := Delimiter;
   Strings.DelimitedText :=  '"' + StringReplace(Input, Delimiter, '"' + Delimiter + '"', [rfReplaceAll]) + '"' ;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit1.Text := 'Users^foo bar^bar foo^foobar^barfoo';
  Split('^',Edit1.Text,Memo1.Lines);
end;

非常感谢!

【讨论】:

【参考方案2】:
sl.Text := StringReplace(S, sl.Delimiter, sLineBreak, [rfReplaceAll]);

【讨论】:

您可能应该添加一个关于这是做什么的解释。【参考方案3】:

Ryan 使用 Delphi 中的 ExtractStrings() 函数为这个问题提供了一个很好的解决方案。见:

Parsing a string using a delimiter to a TStringList, seems to also parse on spaces (Delphi)

因此,在您的情况下,将对 sl.Delimiter 和 sl.DelimitedText 的调用替换为以下行: ExtractStrings(['^'], [], PChar(S), sl);

【讨论】:

【参考方案4】:

您应该将s1.StrictDelimiter := True 设置为不被视为分隔符的空格,更多信息here。

由于您使用的版本不支持上述内容(正如在提交答案后澄清的那样),您有两种选择:

    找到一个您知道不会在原文中使用的字符(例如下划线),在拆分前将所有空格转换为该字符,并在拆分后转换回来。这是robosoft的建议。 如果文本中没有倒排逗号和空格,可以使用Alexander 的技巧,在倒排命令中将文本换行在分隔符之间,使'hello hello^bye bye' 变为'"hello hello"^"bye bye"'。如果您确实选择了这条路径并且它适合您,请接受 Alexander 的回答而不是我的,他还提供了实现它的代码。

不使用StrictDelimiter 的两种变通方法都有局限性:第一种方法需要一些未使用的字符,第二种方法要求原文中没有反引号和空格。

也许是时候升级到较新版本的 Delphi 了 :)

【讨论】:

您想解决什么问题?对我来说似乎是一个解决方案。 您的出发点是阅读 Classes.pas 中 SetDelimitedText 的源代码,以及 TStrings 的子类以创建以您需要的方式处理此问题的版本,或者仅编写一个独立函数在插入符号上拆分字符串并返回一个字符串列表。 你能暂时把空间变成别的东西,然后再把它们改回来吗?通常不会出现在您的列表中的任何其他字符都可以使用。这是一种 hack,或者我们更喜欢“必要的邪恶作为一种解决方法”。 :-) @Todd - 这是我在 Delphi 3 中编写的第一个重要的子类!【参考方案5】:
sl.DelimitedText := '"' + StringReplace(S, sl.Delimiter, '"' + sl.Delimiter + '"', [rfReplaceAll]) + '"';

【讨论】:

废话,你打败了我,我输入的答案完全相同:) 非常聪明,谢谢 Alexander,还有 The_Fox,即使你没有直接帮助我,但你打算这样做 :) +1 非常好,但是如果原始字符串包含像“”“”这样的小节(即文本中的引号和空格) >>> 如果原始字符串包含像 ' " " ' 这样的小节,那么用户名如何包含 '"' char?:) @Alexander - 举个例子:'Bill "The Womanizer" Clinton' :)

以上是关于Delphi:即使设置了 Delimiter,StringList Delimiter 也始终是空格字符的主要内容,如果未能解决你的问题,请参考以下文章

DELPHI7 代码编辑器字体设置问题

delphi 汉字字符串怎么比较

delphi中怎样把字符串分解?

Delphi 中 TStrings 一些用法

delimiter解释

delphi 怎么能以逗号为准把字符串拆分