mdlittle
asked on
String parsing question
I need to parse a string like this:
'9'#$D#$A'[Status]'#$A#$D# $A'e'#$D#$ A'Curr=300 6'#$A#$D#$ A'13'#$D#$ A'Update=6 4'#$A#$D#$ A'b'#$D#$A 'STOP=1'#$ A#$D#$A'b' #$D#$A'PLA Y=0'#$A#$D #$A'c'#$D# $A'PAUSE=0 '#$A#$D#$A 'd'#$D#$A' RANDOM=0'# $A#$D#$A'c '#$D#$A'GR OUP=0'#$A# $D#$A'b'#$ D#$A'MUTE= 0'#$A#$D#$ A'd'#$D#$A 'REPEAT=0' #$A#$D#$A' f'#$D#$A'S tate=Inact ive'#$A#$D #$A'd'#$D# $A'[End Status]'#$A#$D#$A'2'#$D#$A #$D#$A#$D# $A'0'#$D#$ A#$D#$A
and need to get the "key=value" strings such as Update=64. The keys are constants but the values are not. I think this is an easy one but it has been a while for me and I am lazy.
'9'#$D#$A'[Status]'#$A#$D#
and need to get the "key=value" strings such as Update=64. The keys are constants but the values are not. I think this is an easy one but it has been a while for me and I am lazy.
var s : string;
KeyPosn : integer;
ValuePosn : integer;
DelimPosn : integer;
sKeyValue : string;
iKeyValue : integer;
// the following assignment statement is not syntactically correct
s:='9'#$D#$A'[Status]'#$A# $D#$A'e'#$ D#$A'Curr= 3006'#$A#$ D#$A'13'#$ D#$A'Updat e=64'#$A#$ D#$A'b'#$D #$A'STOP=1 '#$A#$D#$A 'b'#$D#$A' PLAY=0'#$A #$D#$A'c'# $D#$A'PAUS E=0'#$A#$D #$A'd'#$D# $A'RANDOM= 0'#$A#$D#$ A'c'#$D#$A 'GROUP=0'# $A#$D#$A'b '#$D#$A'MU TE=0'#$A#$ D#$A'd'#$D #$A'REPEAT =0'#$A#$D# $A'f'#$D#$ A'State=In active'#$A #$D#$A'd'# $D#$A'[End
Status]'#$A#$D#$A'2'#$D#$A #$D#$A#$D# $A'0'#$D#$ A#$D#$A ;
KeyPosn:=Pos('Curr=',s);
ValuePosn:=KeyPosn + 4; //Length('Curr=') = 4
s := Copy(s, ValuePosn, Length(s));
DelimPosn := Pos('''',s);
iKeyValue := StrToInt(Copy(s, 1, DelimPosn));
KeyPosn:=Pos('State=',s);
ValuePosn:=KeyPosn + 6; //Length('State=') = 6
s := Copy(s, ValuePosn, Length(s));
DelimPosn := Pos('''',s);
sKeyValue := Copy(s, 1, DelimPosn);
Note: I've provided you with code to parse an integer value and a string value. I leave it to you to add the other key=value parse code snippets and save them in the appropriate places.
good luck
KeyPosn : integer;
ValuePosn : integer;
DelimPosn : integer;
sKeyValue : string;
iKeyValue : integer;
// the following assignment statement is not syntactically correct
s:='9'#$D#$A'[Status]'#$A#
Status]'#$A#$D#$A'2'#$D#$A
KeyPosn:=Pos('Curr=',s);
ValuePosn:=KeyPosn + 4; //Length('Curr=') = 4
s := Copy(s, ValuePosn, Length(s));
DelimPosn := Pos('''',s);
iKeyValue := StrToInt(Copy(s, 1, DelimPosn));
KeyPosn:=Pos('State=',s);
ValuePosn:=KeyPosn + 6; //Length('State=') = 6
s := Copy(s, ValuePosn, Length(s));
DelimPosn := Pos('''',s);
sKeyValue := Copy(s, 1, DelimPosn);
Note: I've provided you with code to parse an integer value and a string value. I leave it to you to add the other key=value parse code snippets and save them in the appropriate places.
good luck
load or assign (text-property) it into a tstringlist
you could code a function like this
var
sl : tstringlist;
result : String;
begin
sl := tstringlist.create;
try
try
sl.text := 'YousrString Above';
result := sl.Value[sl.IndexOfName('Y ourKeyStri ng')];
finally
sl.free;
except
showmessage('An Error');
raise:
end;
end;
hope this helps
meikl ;-)
you could code a function like this
var
sl : tstringlist;
result : String;
begin
sl := tstringlist.create;
try
try
sl.text := 'YousrString Above';
result := sl.Value[sl.IndexOfName('Y
finally
sl.free;
except
showmessage('An Error');
raise:
end;
end;
hope this helps
meikl ;-)
sorry there where much typos above
a tested sample
unit sl_value_u;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Edit2: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
function getvalue(akey : String) : String;
var
sl : tstringlist;
begin
sl := tstringlist.create;
try
try
sl.text := '9'#$D#$A'[Status]'#$A#$D# $A'e'#$D#$ A'Curr=300 6'#$A#$D#$ A'13'#$D#$ A'Update=6 4'#$A#$D#$ A'b'#$D#$A 'STOP=1'#$ A#$D#$A'b' #$D#$A'PLA Y=0'#$A#$D #$A'c'#$D# $A'PAUSE=0 '#$A#$D#$A 'd'#$D#$A' RANDOM=0'# $A#$D#$A'c '#$D#$A'GR OUP=0'#$A# $D#$A'b'#$ D#$A'MUTE= 0'#$A#$D#$ A'd'#$D#$A 'REPEAT=0' #$A#$D#$A' f'#$D#$A'S tate=Inact ive'#$A#$D #$A'd'#$D# $A'[EndSta tus]'#$A#$ D#$A'2'#$D #$A#$D#$A# $D#$A'0'#$ D#$A#$D#$A ;
result := sl.Values[Akey];
finally
sl.free;
end;
except
showmessage('An Error');
raise;
end;
end;
procedure TForm1.Button1Click(Sender : TObject);
begin
edit2.text := getValue(edit1.text);
end;
end.
meikl ;-)
a tested sample
unit sl_value_u;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Edit2: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
function getvalue(akey : String) : String;
var
sl : tstringlist;
begin
sl := tstringlist.create;
try
try
sl.text := '9'#$D#$A'[Status]'#$A#$D#
result := sl.Values[Akey];
finally
sl.free;
end;
except
showmessage('An Error');
raise;
end;
end;
procedure TForm1.Button1Click(Sender
begin
edit2.text := getValue(edit1.text);
end;
end.
meikl ;-)
meikl,
Thanks for teaching me something I didn't know. Your answer is prefered.
Thanks for teaching me something I didn't know. Your answer is prefered.
ASKER
kretzschmar:
Your solution worked very nicely. Thanks for the help. Let me ask you another related question. How would I parse the following:
[sample 1]
key=value
key2=value2
key3=value3
[end sample 1]
[sample 2]
key=value
key2=value2
key3=value3
[end sample 2]
I need to key=value for each sample. The keys are constants.
Your solution worked very nicely. Thanks for the help. Let me ask you another related question. How would I parse the following:
[sample 1]
key=value
key2=value2
key3=value3
[end sample 1]
[sample 2]
key=value
key2=value2
key3=value3
[end sample 2]
I need to key=value for each sample. The keys are constants.
ASKER
kretzschmar:
I forgot the string is loaded with lots of control character as was the first string above. Thanks for your help. Do you want the points?? Please make your next comment an answer so I can award the points.
I forgot the string is loaded with lots of control character as was the first string above. Thanks for your help. Do you want the points?? Please make your next comment an answer so I can award the points.
if it is still on your hard drive, try the Tinifile component:
http://delphi.about.com/library/weekly/aa120401a.htm
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=568&lngWId=7
http://www.delphicorner.f9.co.uk/articles/wapi7.htm
Extended TIniFile:
http://www.undu.com/DN960901/00000018.htm
http://delphi.about.com/library/weekly/aa120401a.htm
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=568&lngWId=7
http://www.delphicorner.f9.co.uk/articles/wapi7.htm
Extended TIniFile:
http://www.undu.com/DN960901/00000018.htm
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Im not very sure what is what you want. In any case, every parsing problem I have I use this unit. Maybe this can be helpful.
best regards
Manuel Lopez (lopem)
{\\\\\\\\\\\\\\\\\\\\\\\\\
{ TechnoJocks Turbo Toolkit v4.00 Released: Feb 1, 1988 }
{ }
{ Module: StrngTTT -- string manipulation routines }
{ }
{ Copyright R. D. Ainsbury (c) 1986 }
{\\\\\\\\\\\\\\\\\\\\\\\\\
unit StrngTTT;
interface
Function PadLeft(Str:string;Size:by
Function PadCenter(Str:string;Size:
Function PadRight(Str:string;Size:b
Function Last(N:byte;Str:string):st
Function First(N:byte;Str:string):s
Function Upper(Str:string):string;
Function Lower(Str:string):string;
Function Proper(Str:string):string;
Function OverType(N:byte;StrS,StrT:
Function Strip(L,C:char;Str:string)
Function LastPos(C:Char;Str:string)
Function PosWord(Wordno:byte;Str:st
Function WordCnt(Str:string):byte;
Function ExtractWords(StartWord,NoW
Function Str_to_Int(Str:string):int
Function Real_to_str(Number:real;De
Function Int_to_Str(Number:longint)
implementation
Function PadLeft(Str:string;Size:by
var temp : string;
begin
Fillchar(Temp[1],Size,Pad)
SetLength(Temp,Size);
If Length(Str) <= Size then
Move(Str[1],Temp[1],length
else
Move(Str[1],Temp[1],size);
PadLeft := Temp;
end;
Function PadCenter(Str:string;Size:
var temp : string;
L : byte;
begin
Fillchar(Temp[1],Size,Pad)
SetLength(Temp,Size);
L := length(Str);
If L <= Size then
Move(Str[1],Temp[((Size - L) div 2) + 1],L)
else
Move(Str[((L - Size) div 2) + 1],Temp[1],Size);
PadCenter := temp;
end; {center}
Function PadRight(Str:string;Size:b
var
temp : string;
L : integer;
begin
Fillchar(Temp[1],Size,Pad)
SetLength(Temp,Size);
L := length(Str);
If L <= Size then
Move(Str[1],Temp[succ(Size
else
Move(Str[1],Temp[1],size);
PadRight := Temp;
end;
Function Last(N:byte;Str:string):st
var Temp : string;
begin
If N > length(Str) then
Temp := Str
else
Temp := copy(Str,succ(length(Str) - N),N);
Last := Temp;
end; {Func Last}
Function First(N:byte;Str:string):s
var Temp : string;
begin
If N > length(Str) then
Temp := Str
else
Temp := copy(Str,1,N);
First := Temp;
end; {Func First}
Function Upper(Str:string):string;
var
I : integer;
begin
For I := 1 to length(Str) do
Str[I] := Upcase(Str[I]);
Upper := Str;
end; {Func Upper}
Function Lower(Str:string):string;
var
I : integer;
begin
For I := 1 to length(Str) do
If ord(Str[I]) in [65..90] then
Str[I] := chr(ord(Str[I]) + 32);
Lower := Str;
end; {Func Lower}
Function Proper(Str:string):string;
var
I : integer;
SpaceBefore: boolean;
begin
SpaceBefore := true;
Str := lower(Str);
For I := 1 to length(Str) do
If SpaceBefore and (ord(Str[I]) in [97..122]) then
begin
SpaceBefore := False;
Str[I] := Upcase(Str[I]);
end
else
If (SpaceBefore = False) and (Str[I] = ' ') then
SpaceBefore := true;
Proper := Str;
end;
Function OverType(N:byte;StrS,StrT:
{Overlays StrS onto StrT at Pos N}
var
L : byte;
StrN : string;
begin
L := N + pred(length(StrS));
If L < length(StrT) then
L := length(StrT);
If L > 255 then
Overtype := copy(StrT,1,pred(N)) + copy(StrS,1,255-N)
else
begin
Fillchar(StrN[1],L,' ');
SetLength(StrN,L);
Move(StrT[1],StrN[1],lengt
Move(StrS[1],StrN[N],lengt
OverType := StrN;
end;
end; {Func OverType}
Function Strip(L,C:char;Str:string)
{L is left,center,right,all,ends
var I : byte;
begin
Case Upcase(L) of
'L' : begin {Left}
While Str[1] = C do
Delete(Str,1,1);
end;
'R' : begin {Right}
While Str[length(Str)] = C do
Delete(Str,length(Str),1);
end;
'B' : begin {Both left and right}
While Str[1] = C do
Delete(Str,1,1);
While Str[length(Str)] = C do
Delete(Str,length(Str),1);
end;
'A' : begin {All}
I := 1;
Repeat
If Str[I] = C then
Delete(Str,I,1)
else
I := succ(I);
Until (I > length(Str)) or (Str = '');
end;
end;
Strip := Str;
end; {Func Strip}
Function LastPos(C:Char;Str:string)
Var I : byte;
begin
I := succ(Length(Str));
Repeat
I := Pred(I);
Until (I = 0) or (Str[I] = C);
LastPos := I;
end; {Func LastPos}
Function LocWord(StartAT,Wordno:byt
{local proc used by PosWord and Extract word}
var
W,L: integer;
Spacebefore: boolean;
begin
If (Str = '') or (wordno < 1) or (StartAT > length(Str)) then
begin
LocWord := 0;
exit;
end;
SpaceBefore := true;
W := 0;
L := length(Str);
StartAT := pred(StartAT);
While (W < Wordno) and (StartAT <= length(Str)) do
begin
StartAT := succ(StartAT);
If SpaceBefore and (Str[StartAT] <> ' ') then
begin
W := succ(W);
SpaceBefore := false;
end
else
If (SpaceBefore = false) and (Str[StartAT] = ' ') then
SpaceBefore := true;
end;
If W = Wordno then
LocWord := StartAT
else
LocWord := 0;
end;
Function PosWord(Wordno:byte;Str:st
begin
PosWord := LocWord(1,wordno,Str);
end; {Func Word}
Function WordCnt(Str:string):byte;
var
W,I: integer;
SpaceBefore: boolean;
begin
If Str = '' then
begin
WordCnt := 0;
exit;
end;
SpaceBefore := true;
W := 0;
For I := 1 to length(Str) do
begin
If SpaceBefore and (Str[I] <> ' ') then
begin
W := succ(W);
SpaceBefore := false;
end
else
If (SpaceBefore = false) and (Str[I] = ' ') then
SpaceBefore := true;
end;
WordCnt := W;
end;
Function ExtractWords(StartWord,NoW
var Start, finish : integer;
begin
If Str = '' then
begin
ExtractWords := '';
exit;
end;
Start := LocWord(1,StartWord,Str);
If Start <> 0 then
finish := LocWord(Start,succ(NoWords
else
begin
ExtractWords := '';
exit;
end;
If finish <> 0 then
Repeat
finish := pred(finish);
Until Str[finish] <> ' '
else
finish := length(Str);
ExtractWords := copy(Str,Start,succ(finish
end; {Func ExtractWords}
Function Int_to_Str(Number:longint)
var Temp : string;
begin
Str(Number,temp);
Int_to_Str := temp;
end;
Function Str_to_Real(Str:string):re
var temp,code : integer;
begin
If length(Str) = 0 then
Str_to_Real := 0
else
begin
If Copy(Str,1,1)='.' Then
Str:='0'+Str;
If (Copy(Str,1,1)='-') and (Copy(Str,2,1)='.') Then
Insert('0',Str,2);
If Str[length(Str)] = '.' then
Delete(Str,length(Str),1);
val(Str,temp,code);
if code = 0 then
Str_to_Real := temp
else
Str_to_Real := 0;
end;
end;
function Real_to_str(Number:real;De
var Temp : string;
begin
Str(Number:20:Decimals,Tem
repeat
If copy(Temp,1,1) = ' ' then delete(Temp,1,1);
until copy(temp,1,1) <> ' ';
Real_to_Str := Temp;
end;
Function Str_to_Int(Str:string):int
var temp,code : integer;
begin
If length(Str) = 0 then
Str_to_Int := 0
else
begin
val(Str,temp,code);
if code = 0 then
Str_to_Int := temp
else
Str_to_Int := 0;
end;
end;
end.