![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Парсер строки [D6, XP]
novai © (2009-12-10 07:30:00)есть TStringList со строками типа:
установить 100 100
идти 10 10
задержать 20
повоторить
как правильно пропарсить строки, чтобы получить содержимое в 3х переменных?
например итог парсера первой строки:
var
cmd, param1, param2: strings;
...
парсим строку на выходе получаем:
cmd:= 'идти';
param1:='10';
param2:='10';
Nucer (2009-12-12 14:53:00) [1]Написал на днях процедуру, аналогичную Explode из PHP:
procedure Explode(Separator: Char; S: string; Strings: TStringList; Limit: Integer = 0);
var
I, N: Integer;
Start: Integer;
Done: Boolean;
begin
Strings.BeginUpdate;
try
Strings.Clear;
if S = '' then Exit;
N := 0;
Start := 1;
Done := False;
repeat
Inc(N);
I := PosEx(Separator, S, Start);
if (I = 0) or (N = Limit) then
begin
I := Length(S) + 1;
Done := True;
end;
Strings.Add(Copy(S, Start, I - Start));
Start := I + 1;
until Done;
finally
Strings.EndUpdate;
end;
end;
Насколько могу судить, код оптимальный. Значительно ускорить разделение вряд ли получится.
Explode(' ', 'установить 100 100', MyStringList, 3);
Rouse_ (2009-12-12 14:23:00) [2]Вот кстати пример: http://www.cyberguru.ru/delphi-sources/classes-vcl/primer-tparser.html
ЗЫ: вообще я им спокойно исходники парсил для графа зависимостей модулей проекта - целый простор для творчества
Rouse_ (2009-12-12 14:19:00) [3]А чем стандартный TParser из Classes не устраивает?
angvelem (2009-12-12 04:30:00) [4]
> зачем мне еще сторонние компоненты? для этой цели и свое
> подойдет...
> всем спасибо, остановлюсь на своем варианте...
RX тем и хорош, что идёт в исходниках. Выбирай любую процедуру (функцию) и используй или корректируё под себя.
novai (2009-12-10 11:15:00) [5]
> Если ты гарантируешь, что строки в файле не могут быть иными,
> нежели вида
да все слитно и разделено пробелами, значит на 33 посте остановлюсь...
еще раз - Спасибо!
Сергей М. (2009-12-10 11:08:00) [6]Если ты гарантируешь, что строки в файле не могут быть иными, нежели вида
xxx yyy zzz
то достаточно [33]
novai (2009-12-10 11:05:00) [7]тогда всеж буту применять:
> OtherStringList.CommaText := StringReplace(MyStringList[i],
> ' ', ',', [rfReplaceAll]);
для замены моего разделителя пробел, на его разделитель запятую перед комматекст...
Сергей М. (2009-12-10 11:03:00) [8]> почему работает с разделителем пробел?
Это "подводная" особенность парсера в составе стринглиста.
Лучше на нее не полагаться, ибо при CommaText-парсинге строки вида
xxx , yyy , zzz
грабли будут обеспечены
novai (2009-12-10 11:03:00) [9]
> clickmaker © (10.12.09 11:01) [35]
спасибо за разъяснения...
Сергей М. (2009-12-10 11:01:00) [10]
> novai
Ты, конечно, можешь хранить в файле свои строки и с разделителями-пробелами, но тогда придется делать доп.телодвижения, не лучшим образом сказывающиеся на сквозной производительности:
OtherStringList.CommaText := StringReplace(MyStringList[i], ' ', ',', [rfReplaceAll]);
clickmaker (2009-12-10 11:01:00) [11]> почему работает с разделителем пробел? ведь нужен разделитель
> запятая?
справку нифига не читаем
When assigning CommaText, the value is parsed as SDF formatted text. For SDF format, strings are separated by commas or spaces, and optionally enclosed in double quotes. Double quote marks that are part of the string are repeated to distinguish them from the quotes that surround the string. Spaces and commas that are not contained within double quote marks are delimiters. Two commas next to each other will indicate an empty string, but spaces that appear next to another delimiter are ignored. For example, suppose CommaText is set to:
"Stri,ng 1", "Stri""ng 2" , String 3,String4
The list will then contain:
Stri,ng 1
Stri"ng 2
String
3
String4
novai (2009-12-10 10:59:00) [12]попробовал вот так:
d.CommaText:='1 2 3';
memo1.Lines.Add( d.Strings[0]);
memo1.Lines.Add( d.Strings[1]);
memo1.Lines.Add( d.Strings[2]);
d.Free;
почему работает с разделителем пробел? ведь нужен разделитель запятая?
остановлюсь на этом варианте... Спасибо Сергей!
Медвежонок Пятачок (2009-12-10 10:55:00) [13]я понял, но это опять доп. модуль...
этот модуль такой же "дополнительный" как и модуль стринглиста
Сергей М. (2009-12-10 10:49:00) [14]
> у меня более ресурсоемко?
Конечно)
> пример для TStringList.CommaText
OtherStringList.CommaText := MyStringList[i];
в рез-те в OtherStringList[0] - имя команды, а в OtherStringList[>0] - возможные параметры
novai (2009-12-10 10:43:00) [15]
> и не идет ни в какое сравнение с тем что ты налепил в [1]
те у меня более ресурсоемко?
можно пример для TStringList.CommaText?
> xml документ.
я понял, но это опять доп. модуль... да и я не думаю, что он предназначен для таких мелочей, как моя...
Медвежонок Пятачок (2009-12-10 10:39:00) [16]xml документ.
получение значения атрибута узла по имени этого атрибута.
cmd := inode.attributes['cmd'];
param1 := inode.attributes['param1'];
....
Сергей М. (2009-12-10 10:38:00) [17]
> к чему Вы спросили?
К тому что про TStringList.CommaText тебе уже был намек.
Но ты уперся - "у меня проще".
А намек был неспроста - CSV-парсер в составе TStringList.CommaText достаточно оптимален и по производительности и по ресурсам, и не идет ни в какое сравнение с тем что ты налепил в [1]
novai (2009-12-10 10:35:00) [18]
> одна команда занимает ровно одну строку. ничего иного в
> "требованиях" не сказано
да, а теперь простейший обработчик, чтобы выбрать параметры и занести в переменные...
novai (2009-12-10 10:34:00) [19]
> И где в этих требованиях фигурирует недопустимость использование
> запятой в кач-ве разделителя ?
вообще, нужен пробел, но возможно и запятую, а это к чему Вы спросили?
Сергей М. (2009-12-10 10:30:00) [20]
> novai
И где в этих требованиях фигурирует недопустимость использование запятой в кач-ве разделителя ?