Проблема
Если текст в 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;
Работает для всех протестированных символов, ярешил не смешивать цитируемые и десятичные символы для удобства чтения.Единственный вопрос сейчас, который быстрее?Я думаю, что мой обходной путь будет быстрее, так как я проверяю каждый символ на соответствие всем тем, что ищу, тогда как при использовании функции System.Pos я выполняю одну и ту же процедуру синтаксического анализа 4 раза.
Решение
После некоторого тестирования, это зависит от того, какие символы вы ищете.Тестирование это с запятой (# 44), расположенной 294k символов в строку длиной 589k.Функция, использующая System.Pos, имеет производительность ~ 390 микросекунд, а оператор case выполняет ~ 700 микросекунд.
ОДНАКО!
Если вы измените символ в строке на перевод строки (# 10), то для System.Pos это займет намного больше времени (~ 2700 микросекунд)) из-за повторных звонков.Оператор case все еще работает ~ 700 микросекунд.
Так что я думаю, что если вы ищете определенного персонажа, то System.Pos определенно является подходящим вариантом, однако если вы ищете несколько (что делает мое приложение), то повторный вызов не требуется, когда выможно просто отсканировать его и использовать оператор case.