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

发布于 2024-08-03 04:42:33 字数 441 浏览 2 评论 0原文

我在 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 ' '

有什么想法吗?

I am having trouble with the delimiter in the TStringList Class. Take a look:

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] SHOULD return 'foo bar'

sl[1] DOES return 'foo'

It seems that the delimiter is now '^' AND ' '

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

樱&纷飞 2024-08-10 04:42:33

您应该设置 s1.StrictDelimiter := True 以使空格不被视为分隔符,更多信息此处

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

  1. 查找您知道在原始文本中不会使用的字符(例如下划线),将所有空格转换为分割前的字符,并在分割后转换回来。这是 robosoft 的建议。
  2. 如果文本中没有引号和空格,则可以使用 Alexander 的技巧,将文本换行反转命令中的分隔符,以便 'hello hello^bye bye' 变为 '"hello hello"^"bye bye"'。如果您确实选择了这条路径并且它适合您,请接受亚历山大的答案而不是我的答案,他还提供了实现它的代码。

两种不使用 StrictDelimiter 的解决方法都有局限性:第一个需要一些未使用的字符,第二个不需要原始文本中的引号和空格。

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

You should set s1.StrictDelimiter := True for spaces not to be considered delimiters, more info here.

Since you work in a version that does not support the above (as was clarified after the answer was submitted), you have two options:

  1. Find a character you know will not be used in the original text (e.g. underscore), convert all spaces to that character before splitting, and convert back after splitting. This is robosoft's suggestion.
  2. If you don't have inverted commas and spaces in the text, you can use Alexander's trick and wrap the text between delimiters in inverted command, so that 'hello hello^bye bye' turns to '"hello hello"^"bye bye"'. If you do choose this path and it works for you, please accept Alexander's answer and not mine, he also provides the code to implement it.

Both workarounds not using StrictDelimiter have limitations: the first requires some unused character, and the second requires no inverted commas and spaces in the original text.

Maybe it's time to upgrade to a newer version of Delphi :)

扎心 2024-08-10 04:42:33
sl.DelimitedText := '"' + StringReplace(S, sl.Delimiter, '"' + sl.Delimiter + '"', [rfReplaceAll]) + '"';
sl.DelimitedText := '"' + StringReplace(S, sl.Delimiter, '"' + sl.Delimiter + '"', [rfReplaceAll]) + '"';
岁月如刀 2024-08-10 04:42:33

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

使用 TStringList 的分隔符解析字符串,似乎也会解析空格(Delphi)

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

Ryan has provider an excellent solution to this problem using ExtractStrings() function in Delphi. See:

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

So in your case, replace calls to sl.Delimiter and sl.DelimitedText with the line below:
ExtractStrings(['^'], [], PChar(S), sl);

奢望 2024-08-10 04:42:33

Delphi 7 的工作对我来说“就像手套一样”。这是我应用亚历山大技巧后的功能:

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;

非常感谢!

Work's in Delphi 7 "like gloves" for me. This is my function after apply 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;

Thanks a lot!

_蜘蛛 2024-08-10 04:42:33
sl.Text := StringReplace(S, sl.Delimiter, sLineBreak, [rfReplaceAll]);
sl.Text := StringReplace(S, sl.Delimiter, sLineBreak, [rfReplaceAll]);
泛滥成性 2024-08-10 04:42:33
var
  MyString: String;
  Splitted: TArray<String>;

begin
  MyString := String.Join(',', ['String1', 'String2', 'String3']);
  Splitted := MyString.Split([','], 2);
end.

选项:

Count :返回的最大分割数;如果未指定,则默认为 MaxInt。

QuoteStart/QuoteEnd :忽略分隔符的字符串引用部分的开始和结束字符。

选项:控制是否有任何空匹配,或者是否包含尾随空匹配。

更多信息

var
  MyString: String;
  Splitted: TArray<String>;

begin
  MyString := String.Join(',', ['String1', 'String2', 'String3']);
  Splitted := MyString.Split([','], 2);
end.

options:

Count : Maximum number of splits to return; defaults to MaxInt if not specified.

QuoteStart/QuoteEnd : Start and end characters of a quoted part of the string where the separator is ignored.

Options : Controls if any empty matches, or if trailing empty matches are included.

More info

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文