В первой части я рассказал, как можно разбить строку на слова, числа, в общем на подстроки, которые находятся между пробелами в строке. Так вот как я уже говорил, первый метод не совсем быстрый и не совсем стабильный. Поэтому я пишу про статью про TParser - это класс, как я уже говорил, предназначен для разбора строки на слова, целочисленный данные, вещественные данные и многое другое. Этот класс поможет Вам разобрать математическое выражение и в нужном порядке выполнить его, конечно не получится «мего«-крутое выражение разобрать, но небольшие вполне.
На форме у меня следующие компоненты
- TButton
- TEdit
- TListBox
Тут есть еще одно но, то, что TParser работает только с потоковыми данными, то есть с TStream. Но проблемы в потоковую переменную записать текст труда не составит, поэтому нам необходимо сначала ее создать, затем загрузить в TParser и начать работать.
На событие OnClick кнопки я написал следующий код
procedure TForm1.Button1Click(Sender: TObject);
var
s:String;
Stream:TStream;
Parser:TParser;
begin
try
s:=Edit1.Text;
Stream:=TMemoryStream.Create;
Stream.WriteBuffer(s[1],length(s));
Stream.Position:=0;
Parser:=TParser.Create(Stream);
while Parser.Token<>toEOF do
begin
if Parser.Token=toSymbol then
ListBox1.Items.Add(Parser.TokenString);
Parser.NextToken;
end;
except
on e:Exception do
end;
end;
Как я и говорил, создается переменная потоковая, затем обязательно в ее позиции необходимо установить в 0. Далее мы создаем наш TParser и при создании загружаем в него нашу потоковую переменную. Далее у нас идет цикл, toEof - означает пока не конец потоковой переменной. Token - это наши подстроки, которые добавляются в TListBox. NextToken - переходит к следующей подстроке. TokenString - это тип нашей подстроки, которую мы добавляем. Данный пример добавляет только текстовые подтсроки.
Например строка
- 111 hello 222
В результате в TListBox будет «hello«, если нам надо разбить строку только на числа, то код будет следующим
procedure TForm1.Button1Click(Sender: TObject);
var
s:String;
Stream:TStream;
Parser:TParser;
begin
try
s:=Edit1.Text;
Stream:=TMemoryStream.Create;
Stream.WriteBuffer(s[1],length(s));
Stream.Position:=0;
Parser:=TParser.Create(Stream);
while Parser.Token<>toEOF do
begin
if Parser.Token=toInteger then
ListBox1.Items.Add(IntToStr(Parser.TokenInt));
Parser.NextToken;
end;
except
on e:Exception do
end;
end;
То есть из строки
- 111 hello 222 333
Добавиться 111 222 333. Если необходимо разбить на все подстроки, хоть там и слова и числа, то просто необходимо убрать условие на проверку входимости в ту или иную подстроку определенного типа и код будет следующим
procedure TForm1.Button1Click(Sender: TObject);
var
s:String;
Stream:TStream;
Parser:TParser;
begin
try
s:=Edit1.Text;
Stream:=TMemoryStream.Create;
Stream.WriteBuffer(s[1],length(s));
Stream.Position:=0;
Parser:=TParser.Create(Stream);
while Parser.Token<>toEOF do
begin
ListBox1.Items.Add(Parser.TokenString);
Parser.NextToken;
end;
except
on e:Exception do
end;
end;
Как видите скорость при больших объемах увеличиться для обработки этих данных, а при первом методе будет совсем маленькой. Также кода намного меньше написано, что тоже есть хорошо.