我使用StrUtils
将字符串拆分为TStringDynArray
,但输出不符合预期。我将尝试解释这个问题:
我有一个字符串str
:'a'; 'b'; 'c'
现在我调用StrUtils.SplitString(str, '; ');
来分割字符串,我期望一个包含三个元素的数组:'a'
,'b'
,'c'
但我得到的是一个包含五个元素的数组:'a'
,''
,'b'
,''
,'c'
。
当我只用';'
而不是'; '
进行拆分时,我会得到三个带有前导空格的元素。
那么为什么我在第一个解决方案中得到空字符串?
答案 0 :(得分:15)
此功能旨在不合并连续的分隔符。例如,考虑在逗号上拆分以下字符串:
foo,,bar
您期望SplitString('foo,,bar', ',')
返回什么?您是在寻找('foo', 'bar')
还是应该回答('foo', '', 'bar')
?它并不清楚先验是正确的,不同的用例可能需要不同的输出。
如果是您的情况,您指定了两个分隔符,';'
和' '
。这意味着
'a'; 'b'
在';'
分割,再在' '
分割。在这两个分隔符之间没有任何内容,因此在'a'
和'b'
之间返回一个空字符串。
XE3中引入的Split
中的string helper方法具有TStringSplitOptions
参数。如果为该参数传递ExcludeEmpty
,则将连续分隔符视为单个分隔符。这个计划:
{$APPTYPE CONSOLE}
uses
System.SysUtils;
var
S: string;
begin
for S in '''a''; ''b''; ''c'''.Split([';', ' '], ExcludeEmpty) do begin
Writeln(S);
end;
end.
输出:
'a' 'b' 'c'
但是你在XE2中没有这个,所以我认为你将不得不推出自己的分割功能。这可能是这样的:
function IsSeparator(const C: Char; const Separators: string): Boolean;
var
sep: Char;
begin
for sep in Separators do begin
if sep=C then begin
Result := True;
exit;
end;
end;
Result := False;
end;
function Split(const Str, Separators: string): TArray<string>;
var
CharIndex, ItemIndex: Integer;
len: Integer;
SeparatorCount: Integer;
Start: Integer;
begin
len := Length(Str);
if len=0 then begin
Result := nil;
exit;
end;
SeparatorCount := 0;
for CharIndex := 1 to len do begin
if IsSeparator(Str[CharIndex], Separators) then begin
inc(SeparatorCount);
end;
end;
SetLength(Result, SeparatorCount+1); // potentially an over-allocation
ItemIndex := 0;
Start := 1;
CharIndex := 1;
for CharIndex := 1 to len do begin
if IsSeparator(Str[CharIndex], Separators) then begin
if CharIndex>Start then begin
Result[ItemIndex] := Copy(Str, Start, CharIndex-Start);
inc(ItemIndex);
end;
Start := CharIndex+1;
end;
end;
if len>Start then begin
Result[ItemIndex] := Copy(Str, Start, len-Start+1);
inc(ItemIndex);
end;
SetLength(Result, ItemIndex);
end;
当然,所有这些都假设您希望空间充当分隔符。您已经在代码中询问了这一点,但实际上您可能只希望;
充当分隔符。在这种情况下,您可能希望将';'
作为分隔符传递,并修剪返回的字符串。
答案 1 :(得分:14)
SplitString
定义为
function SplitString(const S, Delimiters: string): TStringDynArray;
有人会认为Delimiters
表示用于拆分字符串的单个分隔符字符串,但它实际上表示用于拆分字符串的单个字符集。 Delimiters
字符串中的每个字符都将用作可能的分隔符之一。
将字符串拆分为由指定分隔的不同部分 分隔符字符。 SplitString将字符串拆分为不同的部分 由指定的分隔符字符分隔。 S是字符串 分裂。分隔符是包含定义为的字符的字符串 分隔符。
答案 2 :(得分:5)
这是因为SplitString的第二个参数是单个字符分隔符的列表,所以&#39 ;; &#39;意味着分裂为&#39 ;;&#39;或拆分为&#39; &#39 ;.所以字符串在每个&#39;;&#39;在每个空间,以及&#39 ;;&#39;而且&#39; &#39;什么都没有,因此是空的。