如果TRichEdit中的文字是这样的话;
'hello, world'#$D#$A
然后以下例程显示TRUE。但是当RichEdit有
时'test'#$D#$A#$D#$A'test'#$D#$A#$D#$A'test'#$D#$A
然后例程显示FALSE。在我看来它是有缺陷的,因为它找到了逗号,但不是新行/换行。我创建了一个解决方法来代替字符串并找到我正在寻找的内容,但我仍然很好奇为什么Delphi函数不起作用。有什么想法吗?
procedure TForm1.Button1Click(Sender: TObject);
var
sTmp : String;
begin
sTmp := RichEdit1.Lines.GetText;
if ( ( Pos( ',', sTmp ) <> 0 ) or
( Pos( '"', sTmp ) <> 0 ) or
( Pos( '\n', sTmp ) <> 0 ) or
( Pos( '\r', sTmp ) <> 0 ) ) then
Label1.Caption := 'TRUE'
else
Label1.Caption := 'FALSE';
end;
function CheckChars( const sData: String ): Boolean;
var
pCur : PChar;
begin
pCur := PChar( sData );
// Exit at NULL terminator
while ( pCur^ <> #0 ) do
begin
case pCur^ of
#13, #10, #34, #44 : Exit(true);
end;
Inc( pCur );
end;
end;
function CheckChars( const sData: String ): Boolean
begin
if ( ( Pos( #44, sData ) <> 0 ) or
( Pos( #34, sData ) <> 0 ) or
( Pos( #13, sData ) <> 0 ) or
( Pos( #10, sData ) <> 0 ) ) then
Result := true
else
Result := false;
end;
适用于所有测试的字符,我决定不混合引用的字符和十进制字符以提高可读性。现在唯一的问题是哪个更快?我认为我的解决方法会更快,因为我正在检查所有我正在寻找的char,而当我使用System.Pos函数时,我运行相同的解析例程4次。
经过一些测试,这取决于您要寻找的是哪种角色。使用逗号(#44)对其进行测试,将294k字符放入589k长度的字符串中。使用System.Pos的函数具有~390微秒的性能,case语句运行约700微秒。
无论其<!/ em>的
如果将字符串中的字符更改为换行符(#10),则由于重复调用,System.Pos(~2700微秒)需要更长的时间。 case语句仍然运行约700微秒。
所以我想如果你在寻找一个特定的角色,那么System.Pos肯定是要走的路,但如果你正在寻找多个(我的应用程序所做的那样),那么当你只需要扫描时就不需要重复调用它并使用案例陈述。
答案 0 :(得分:6)
我不认为Delphi认为\ n是一个新行,Pos认为你实际上是在搜索字符“\”和“n”。
尝试搜索#13
和#10
(回车和换行)(或者您可以使用#$D
和#$A
,这将是十六进制等效。)< / p>
e.g。
if ( ( Pos( ',', sTmp ) <> 0 ) or
( Pos( '"', sTmp ) <> 0 ) or
( Pos( #10, sTmp ) <> 0 ) or
( Pos( #13, sTmp ) <> 0 ) ) then
此外,Delphi字符串也会被计算,但它们总是以#0结尾。无法保证字符串不包含空字符,这意味着您的while循环可能会提前终止。
所以或者你可以循环通过i:= 1到Length(sTmp)(从1开始,因为sTmp [0]是计数器)。
或者您可以将while循环构造为
指数:= 1;
While Index < Length(sTmp) do
begin
case sTmp[Index] of
etc...
答案 1 :(得分:2)
(这实际上是一个评论,但它看起来很恐怖。)
请注意您的整个块
case pCur^ of
#13 : // CR
begin
Result := true;
break;
end;
#10 : // LF
begin
Result := true;
break;
end;
#34 : // Quote
begin
Result := true;
break;
end;
#44 : // Comma
begin
Result := true;
break;
end;
end;
通过注意可以更紧凑地编写
Result := true; break;
与Result := true; Exit;
相同,总是可以写成Exit(true)
。
如果行动相同,可以将几种情况合并为一个案例。
因此你可以写
case pCur^ of
#13, #10, #34, #44: Exit(true);
end;
但更好的是,可以编写整个函数
function CheckChars(const Str: string): boolean;
const
INTERESTING_CHARS = [#13, #10, #34, #44];
var
i: integer;
begin
result := false;
for i := 1 to length(Str) do
if Str[i] in INTERESTING_CHARS then
Exit(true);
end;