看过这样一个例子:
http://www.cnstu.net/3856/3856804.htm我想大家都会觉得简单,可是我由此觉得里面有一个很大的缺陷;
比如:
procedure TForm1.Button1Click(Sender: TObject);
var
sList:TStringList;
str:string;
i:integer;
begin sList:=TStringList.Create;
sList.DelimitedText:=',';
str:='商品 1,商品 2';
sList.Delimiter:=',';
sList.DelimitedText:=Str;
Memo1.Lines:=sList;
end;这样memo1的输出结果是:
商品
1
商品
2而我的本意是要输出 :
商品 1
商品 2除非把上面的
str:='商品 1,商品 2'; 修改成 str:='"商品 1","商品 2"';
但是很多时候这里的str很复杂,而且比如做一个通讯报文分解程序,它传过来的str很复杂,我们人为的去增加"",即增加了复杂度,而且可能根本没有办法判断在哪里加""。真搞不懂,StringList的功能既然那么强大,为什么分割字符串的时候,一定把空格符认为是其中之一的默认分割符,不像用它都不行;晕。
如何利用StringList,实现随心所欲的分割;
指定用那个分割符就有哪了,其他乱七八糟的符号不要进来捣乱;
http://www.cnstu.net/3856/3856804.htm我想大家都会觉得简单,可是我由此觉得里面有一个很大的缺陷;
比如:
procedure TForm1.Button1Click(Sender: TObject);
var
sList:TStringList;
str:string;
i:integer;
begin sList:=TStringList.Create;
sList.DelimitedText:=',';
str:='商品 1,商品 2';
sList.Delimiter:=',';
sList.DelimitedText:=Str;
Memo1.Lines:=sList;
end;这样memo1的输出结果是:
商品
1
商品
2而我的本意是要输出 :
商品 1
商品 2除非把上面的
str:='商品 1,商品 2'; 修改成 str:='"商品 1","商品 2"';
但是很多时候这里的str很复杂,而且比如做一个通讯报文分解程序,它传过来的str很复杂,我们人为的去增加"",即增加了复杂度,而且可能根本没有办法判断在哪里加""。真搞不懂,StringList的功能既然那么强大,为什么分割字符串的时候,一定把空格符认为是其中之一的默认分割符,不像用它都不行;晕。
如何利用StringList,实现随心所欲的分割;
指定用那个分割符就有哪了,其他乱七八糟的符号不要进来捣乱;
解决方案 »
- 如何在tdxdbgrid 里选中多行删除数据
- delphi中的多表查询语句?
- delphi写的DLL,里面的窗口用 close 关不掉,怎么处理?
- 取字符串和避免重复运行
- 简单的问题,up有分!
- 高手请进…………………………………………………………………………20
- DUnit单元测试工具哪里有下载,请指示,十万火急!
- 1000分求救!!我的重 要的数据全部没有了!有没有这样的软件让它恢复!!!!!
- 超难题:用real控件编程时,如何屏蔽real本身的错误信息?重分
- StringGrid的最后一行?
- 如何在一个程序中激活另一个已经被最小化或失去焦点的窗口?
- 一个关于TListbox,TMemo控件的问题。
procedure SplitString(const Source, Ch: string; var sList: TStringList);
var
Temp: string;
i: Integer;
begin
Temp := Source;
i := pos(Ch, Source);
while i <> 0 do
begin
sList.Add(Copy(Temp, 0, i - 1));
Delete(Temp, 1, i + length(Ch) - 1);
i := pos(Ch, Temp);
end;
sList.Add(Temp);
end;但是有了问题:
比如有一个条件字符串
str:='(name like ''% and %'') and (code like ''%123 %'')';
我现在想把它分割成两个字符 (name like ''% and %'') 和 code like ''%123 %'')用我上面函数带入: SplitString(str,' and ',sList );
但是这样得到的结果是:
sList[0]:='(name like ''%'';
sList[1]:='%'')';
sList[2]:='(code like ''%123 %'')';我的原意是不考虑内部字符串的分割,比如 like '....',这里面的内容不应该参与分割;
但是StringList是有这个功能的,我们可以把StringList.QuoteChar='''';就能解决这个问题;所有我想改造这个函数:
procedure SplitString(const Source, Delimiter: string;QuoteChar:char;var sList: TStringList);
beginend;
这里面参数的意义分别是:
Source -- 要分割的字符串,比如 (a='123') and (b=' and ');
Delimiter-- 分割的特征字符或字符串,比如: and
QuoteChar-- 引用特征字字符,表示分割时,Quote里面的字符不参与分割;比如 '希望有朋友能够对该函数功能进行补充;
procedure SplitString(const ASourceStr, ADelimiter: string;AQuoteChar:char;var sList: TStringList);function isQuoteStr(const Source, Delimiter: string;QuoteChar:char;Apos:integer):boolean;
begin
Result:=false;
if (Apos > 1) and (length(Source) >= Apos+length(Delimiter)) then
Result:=(Source[Apos-1]=QuoteChar) and (Source[Apos+length(Delimiter)]=QuoteChar);
end;end;function PosStart(AposStr,ASrcStr:String;Astart:integer=0):integer;
var
Apos:integer;
Atemp:String;
begin
Result:=pos(AposStr,AsrcStr);
if Astart > 0 then
begin
Atemp:=copy(ASrcStr,Astart,Maxint);
Apos:=pos(AposStr,Atemp);
if Apos > 0 then
Result:=Astart+Apos-1;
end;
end;var
i,j:integer;
Temp: string;
begin
Temp := Source;
j:=0;
i:=PosStart(Delimiter,Source,j);
//i := pos(Delimiter, Source);
while i <> 0 do
begin
if not isQuoteStr(Temp,ADelimiter,AQuoteChar,i) then
begin
sList.Add(Copy(Temp, 1, i - 1));
Delete(Temp, 1, i + length(Ch) - 1);
j:=0;
end
else
j:=i+1;
i :=PosStart(Delimiter, Temp);
end;
sList.Add(Temp);
end;
begin
Result:=false;
if (Apos > 1) and (length(Source) >= Apos+length(Delimiter)) then
Result:=(Source[Apos-1]=QuoteChar) and (Source[Apos+length(Delimiter)]=QuoteChar);
end;end;function PosStart(AposStr,ASrcStr:String;Astart:integer=0):integer;
var
Apos:integer;
Atemp:String;
begin
Result:=pos(AposStr,AsrcStr);
if Astart > 0 then
begin
Atemp:=copy(ASrcStr,Astart,Maxint);
Apos:=pos(AposStr,Atemp);
if Apos > 0 then
Result:=Astart+Apos-1;
end;
end;var
i,j:integer;
Temp: string;
begin
Temp := Source;
j:=0;
i:=PosStart(Delimiter,Source,j);
//i := pos(Delimiter, Source);
while i <> 0 do
begin
if not isQuoteStr(Temp,ADelimiter,AQuoteChar,i) then
begin
sList.Add(Copy(Temp, 1, i - 1));
Delete(Temp, 1, i + length(Ch) - 1);
j:=0;
end
else
j:=i+1;
i :=PosStart(Delimiter, Temp,j);
end;
sList.Add(Temp);end;