最近在项目中遇到分割字符串的问题,因为数据量比较大,大概有5万多条,每条字符串用特定的字符隔开。开始用copy来分割,发现效率奇低,后来又用Pchar配合汇编分割,效率有所提高,但还是不是很如意。不知道各位大侠有何高见……附上用copy的方法(用pchar配合汇编的方法因为大部分是公司牛人写的,不便公开,请见谅)function SplitString(const source, ch: string): TResultArray;vartemp: string;i: integer;begintemp := source;i := pos(ch, source);while i <> 0 dobeginSetLength(Result, Length(Result) + 1);Result[Length(Result) - 1] := copy(temp, 0, i - 1);delete(temp, 1, i);i := pos(ch, temp);end;SetLength(Result, Length(Result) + 1);Result[Length(Result)-1] := Temp;end;
解决方案 »
- 一个简单的delphi使用问题,向各位赐教!
- Edit控件失去焦点的时候触发的是什么事件呀?
- 我想找两位专职帮手,待遇可能比较低,工作地点在中关村.不知道有没有感兴趣的?
- 关于获得XP的当前用户名,紧急求教!
- 在delphi中如何连接sql server的数据库,在线急等!!!
- 我在Win2000下用SendARP函数发送ARP数据包,包是发出去了,但收不到MAC
- (急)delphi调试时出现这个Project Project1.exe raised exception class EAccessViolation
- 大家能给点参考意见吗??
- 为什么???该死的句柄
- 菜鸟我急需用Delphi控制Access数据库的方法,那位大师可以帮我一下?
- 如何判断出DBGRID中有没有显示记录??
- ComboBox的问题,五分钟结贴100分
procedure SplitString(const source, ch: string; StringList: TStrings);
begin
StringList.Text := StringReplace(Source, ch, #$D#$A, [rfReplaceAll]);
end; var
StringList: TStringList;
begin
StringList := TStringList.Create;
try
SplitString('a,b,c,d...', ',', StringList);
//StringList[0] = 'a', StringList[1] = 'b' ...
...
finally
StringList.Free;
end;
end;
1、效率很低;
2、原串中不能有分隔符的字样;
3、……其实有更好的方法,可以用XML来实现,将字串拼成XML文件或字串,传给对方后对XML进行解析,可以完全解决上面的问题。
用这个方法;
TSTRINGLSIT。COMMATEXT:=‘你要分割的一行’
然后TSTIRNGLIST[0]就可以了;
你的方法是不错,可惜数据源的格式不是由我来决定的 outer2000(天外流星) :没那么容易,分隔符不一定是stringlist的分隔符 lvloj() ( )不错,试试先
如果不是“,”(是的话用 outer2000(天外流星) 兄的方法)分隔,用delphi6,7的话用tstringlist的Delimiter和DelimitedText配合试试
同时将原串当作字符数组看.
对原串进行逐字扫描,
如果不是分隔符,就放到目标字符数组中
如果是分隔符,将目标字符数组中的内容放到一个字符串中
继续对原串扫描,直到结束因为在Delphi中,COPY、Pos 和 Replace等都是基于内存复制的,也就是说所有参数内容都要生成一个副本,如果字符串的长度巨大,则副本的大小就可想而知了
而字符串分割需要N多次的Copy、Pos之类的操作,所以速度就自然大打折扣。
Fills a string list with substrings parsed from a delimited list.UnitClassesCategorystring handling routines (null-terminated)function ExtractStrings(Separators, WhiteSpace: TSysCharSet; Content: PChar; Strings: TStrings): Integer;DescriptionUse ExtractStrings to fill a string list with the substrings of the null-terminated string specified by Content.Separators is a set of characters that are used as delimiters, separating the substrings. Carriage returns, newline characters, and quote characters (single or double) are always treated as separators. Separators are ignored when inside a quoted string until the final end quote. (Note that quoted characters can appear in a quoted string if the quote character is doubled.)WhiteSpace is a set of characters to be ignored when parsing Content if they occur at the beginning of a string.Content is the null-terminated string to parse into substrings.Strings is a string list to which all substrings parsed from Content are added. The string list is not cleared by ExtractStrings, so any strings already in the string list are preserved.ExtractStrings returns the number of strings added to the Strings parameter.Note: ExtractStrings does not add empty strings to the list.
Strings: TStrings): Integer;
var
Head, Tail: PChar;
EOS, InQuote: Boolean;
QuoteChar: Char;
Item: string;
begin
Result := 0;
if (Content = nil) or (Content^=#0) or (Strings = nil) then Exit;
Tail := Content;
InQuote := False;
QuoteChar := #0;
Strings.BeginUpdate;
try
repeat
while Tail^ in WhiteSpace + [#13, #10] do Inc(Tail);
Head := Tail;
while True do
begin
while (InQuote and not (Tail^ in ['''', '"', #0])) or
not (Tail^ in Separators + [#0, #13, #10, '''', '"']) do Inc(Tail);
if Tail^ in ['''', '"'] then
begin
if (QuoteChar <> #0) and (QuoteChar = Tail^) then
QuoteChar := #0
else QuoteChar := Tail^;
InQuote := QuoteChar <> #0;
Inc(Tail);
end else Break;
end;
EOS := Tail^ = #0;
if (Head <> Tail) and (Head^ <> #0) then
begin
if Strings <> nil then
begin
SetString(Item, Head, Tail - Head);
Strings.Add(Item);
end;
Inc(Result);
end;
Inc(Tail);
until EOS;
finally
Strings.EndUpdate;
end;
end;
基本思路是先将字符串放入字符数组中,然后根据特殊间隔字符计算相对位置,再将相对位置以PChar数组的形式返回。以下函数只是个思路,但是pos函数的第二个参数可以是PChar。var TcharArray:Array[0..MaxLen] of Char;
function SplitString(const source, ch: string,var target:TcharArray): TPcharArray;vari,j,k,: integer;beginZeroMemory(@target,Sizeof(target));
MoveMemory(@target,PChar(source),Length(source));
j:=0
i := pos(ch, source);
k:=0;while i <> 0 dobeginResult[k] := PChar(@target[j]);
target[j]:=Char(0); //将间隔字符强制设置成为一个结束符
k:=k+1;
j:=i;
i := pos(ch, PChar(@target[i+1]));end;Result[k] := PChar(@target[j]);
k:=k+1;
j:=i;end;
target[i]:=Char(0); //将间隔字符强制设置成为一个结束符
你的方法虽然有所改进,可是效率决不是最高的,前面有位高人不是说过吗:“因为在Delphi中,COPY、Pos 和 Replace等都是基于内存复制的,也就是说所有参数内容都要生成一个副本,如果字符串的长度巨大,则副本的大小就可想而知了
而字符串分割需要N多次的Copy、Pos之类的操作,所以速度就自然大打折扣。”
cchCount1: Integer; lpString2: PAnsiChar; cchCount2: Integer): Integer; stdcall;
function CompareStringW(Locale: LCID; dwCmpFlags: DWORD; lpString1: PWideChar;
cchCount1: Integer; lpString2: PWideChar; cchCount2: Integer): Integer; stdcall;
function CompareString(Locale: LCID; dwCmpFlags: DWORD; lpString1: PChar;
cchCount1: Integer; lpString2: PChar; cchCount2: Integer): Integer; stdcall;