方法一:
uses IdStrings
var
sl: TStringList;
str: string;
i: Integer;
begin
str := 'aa,b b,cc,dd';
sl := TStringList.Create;
SplitColumns(str, sl, ',');//该函数没有上述的BUG
for i := 0 to sl.Count - 1 do
ShowMessage(sl[i]);
FreeAndNil(sl);
end;
方法二:
{
函数功能:使用自定义分隔符分离字符串并以Stringlist返回
参数说明:
Source: 源字符串
Deli: 自定义分离符
StringList: 返回分离结果
}
procedure SplitString(Source,Deli:string; var StringList :TStringList);
var
EndOfCurrentString: Integer;
begin
if StringList = nil then exit;
StringList.Clear;
while Pos(Deli, Source)>0 do
begin
EndOfCurrentString := Pos(Deli, Source);
StringList.add(Copy(Source, 1, EndOfCurrentString - 1));
Source := Copy(Source, EndOfCurrentString + length(Deli), length(Source) - EndOfCurrentString);
end;
StringList.Add(source);
end;
// 调用
procedure TForm1.Button1Click(Sender: TObject);
var
strlist: TStringList;
begin
strlist := TStringList.Create;
SplitString('123,Channel 1,00000000000000000123,上下线,离线,2013-01-31 09:22:32,公司',
',',
strlist);
ShowMessage(strlist.Text);
end;
方法三:
在delphi中,对于TStringList 进行类似哈希表操作时,DelimitedText会自动判断空格并跳过。
导致reqtext.securityid一直为空,在后续的处理中出错。
function MakePTReqtext(reqtext: PTReqtext; sReqtext:string):Boolean; //902
var
Hash: THashedStringList;
a : TStringList;
fixPkg : TFixPackage;
Buffer : string;
begin
Hash := THashedStringList.Create;
Buffer := Trim(sReqtext);
Hash.DelimitedText := Buffer;
Hash.Delimiter := SOH;
reqtext.MsgType := Hash.Values['35'];
reqtext.IOIID := Hash.Values['23'];
reqtext.IOITransType := Hash.Values['28'];
reqtext.IOIRefID := Getbuff2(Hash.Values['26']);
reqtext.clordid := Hash.Values['11'];
reqtext.OrigClOrdID := Getbuff2(Hash.Values['41']);
reqtext.securityid := Hash.Values['48'];
Simulator.AddLog(1,'解包reqtext.securityid为' + reqtext.securityid);//对于港股的股票代码是5位,会左补空格,此处就会取空。
reqtext.price := Getbuff(Hash.Values['44']);
reqtext.orderqty := Getbuff(Hash.Values['38']);
reqtext.side := Hash.Values['54'];
reqtext.stockholder := GetGroupValue2(Hash,const_NoPartyIDs, 5);;
reqtext.reportseat := GetGroupValue2(Hash,const_NoPartyIDs, 1);
reqtext.branchcode := GetGroupValue2(Hash,const_NoPartyIDs, 4001);
reqtext.text := Hash.Values['58'];
reqtext.UnderlyingSecurityID := Hash.Values['308'];
reqtext.orderSrc := Hash.Values['10901'];
reqtext.PositionEffect := Hash.Values['77'];
reqtext.OrdType := Hash.Values['40'];
reqtext.TimeInForce := Hash.Values['59'];
reqtext.CoveredOrUncovered := Hash.Values['203'];
reqtext.OwnerType := Getbuff(Hash.Values['522']);
reqtext.NoDates := Getbuff(Hash.Values['580']);
reqtext.QuoteReqID := Hash.Values['131'];
reqtext.PartyID := Hash.Values['448'];
reqtext.SecondaryOrderID := Trim(Hash.Values['198']);
if reqtext.SecondaryOrderID = '0' then
reqtext.SecondaryOrderID := '';
reqtext.GroupLeges := GetGroupLegesValue2(Hash);
Hash.Free;
Result := True;
end;
网上找到对于这个问题的解释及解决方法:
TStringList 常用方法与属性&DelimitedText空格问题
//TStringList 常用方法与属性:
var
List: TStringList;
i: Integer;
begin
List := TStringList.Create;
List.Add('Strings1'); {添加}
List.Add('Strings2');
List.Exchange(0,1); {置换}
List.Insert(0,'Strings3'); {插入}
i := List.IndexOf('Strings1'); {第一次出现的位置}
List.Sort; {排序}
List.Sorted := True; {指定排序}
List.Count; {总数}
List.Text; {文本集合}
List.Delete(0); {删除, 0是第一个数据}
List.LoadFromFile('c:/tmp.txt');{打开}
List.SaveToFile('c:/tmp.txt'); {保存}
List.Clear; {清空}
List.Free; {释放}
end;
//读入字符串
var
List: TStringList;
begin
List := TStringList.Create;
List.CommaText := 'aaa,bbb,ccc,ddd';
//相当于: List.Text := 'aaa' + #13#10 + 'bbb' + #13#10' + 'ccc' + '#13#10' + 'ddd';
ShowMessage(IntToStr(List.Count)); //4
ShowMessage(List[0]); //aaa
List.Free;
end;
//置换分隔符
var
List: TStringList;
begin
List := TStringList.Create;
List.Delimiter := '|';
List.DelimitedText := 'aaa|bbb|ccc|ddd';
ShowMessage(IntToStr(List.Count)); //4
ShowMessage(List[0]); //aaa
List.Free;
end;
//类似的哈希表操作法
var
List: TStringList;
begin
List := TStringList.Create;
List.Add('aaa=111');
List.Add('bbb=222');
List.Add('ccc=333');
List.Add('ddd=444');
ShowMessage(List.Names[1]); //bbb
ShowMessage(List.ValueFromIndex[1]); //222
ShowMessage(List.Values['bbb']); //222
//ValueFromIndex 可以赋值:
List.ValueFromIndex[1] := '2';
ShowMessage(List[1]); //bbb=2
//可以通过 Values 赋值:
List.Values['bbb'] := '22';
ShowMessage(List[1]); //bbb=22
List.Free;
end;
//避免重复值
var
List: TStringList;
begin
List := TStringList.Create;
List.Add('aaa');
List.Sorted := True; //需要先指定排序
List.Duplicates := dupIgnore; //如有重复值则放弃
List.Add('aaa');
ShowMessage(List.Text); //aaa
//Duplicates 有3个可选值:
//dupIgnore: 放弃;
//dupAccept: 结束;
//dupError: 提示错误.
List.Free;
end;
//排序与倒排序
{排序函数}
function DescCompareStrings(List: TStringList; Index1, Index2: Integer): Integer;
begin
Result := -AnsiCompareText(List[Index1], List[Index2]);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
List: TStringList;
begin
List := TStringList.Create;
List.Add('bbb');
List.Add('ccc');
List.Add('aaa');
//未排序
ShowMessage(List.Text); //bbb ccc aaa
//排序
List.Sort;
ShowMessage(List.Text); //aaa bbb ccc
//倒排序
List.CustomSort(DescCompareStrings); //调用排序函数
ShowMessage(List.Text); //ccc bbb aaa
//假如:
List.Sorted := True;
List.Add('999');
List.Add('000');
List.Add('zzz');
ShowMessage(List.Text); //000 999 aaa bbb ccc zzz
end;
DelimitedText空格
DelimitedText 空格也默认为分割符的原因很简单:
Borland的程序员把这个属性对应的write方法中的一行代码多加了一个空格。
2种方法解决这个问题。
空格问题的解决方法之一:
先StringReplace用一个特殊字符替代空格,然后StringReplace回来
ss:='aa|bb c| c';
ss:= StringReplace(ss,' ','#',[rfReplaceAll]);
s:= TStringList.Create;
s.Delimiter:= '|';
s.DelimitedText:= ss;
for i:= 0 to s.Count - 1 do
begin
s[i]:= StringReplace(s[i],'#',' ',[rfReplaceAll]);
memo1.Lines.Add(s[i]);
end;
空格问题的解决方法之二:
找到 {DelphiInstDir}/source/Win32/rtl/common/Classes.pas 文件,知道SetDelimitedText函数。如下所示:
注:{DelphiInstDir}为Delphi安装目录
procedure TStrings.SetDelimitedText(const Value: string);
var
P, P1: PChar;
S: string;
begin
BeginUpdate;
try
Clear;
P := PChar(Value);
while P^ in [#1..' '] do
{$IFDEF MSWINDOWS}
P := CharNext(P);
{$ELSE}
Inc(P);
{$ENDIF}
while P^ <> #0 do
begin
if P^ = QuoteChar then
S := AnsiExtractQuotedStr(P, QuoteChar)
else
begin
P1 := P;
// while (P^ > ' ') and (P^ <> Delimiter) do //源代码
while (P^ >= ' ') and (P^ <> Delimiter) do //修改后的代码 请继续往下看
为方便携带,可将Classes.pas 文件重新编译到你的工程文件中即可。步骤:工程-添加到工程-Classes.pas
提醒注意:
对于解决方法2,网上有别的文章写修改后的代码应该是改成(p^ > ''),验证了那样是不可以的,应该用>=' ',
因为这里是对ASCII码比较大小,大于空格' '的都是能显示的,应该判断为大于等于空格。