T0masz
asked on
String split
Hey, I have a string like 234234some describtion.txt Id like to seperate it where the number ends, how would I go about doing it? I was thinking about checking every single char in the string if its a number then if its not start copying the char to a string.
Tom
Tom
Basically FirstLetterInString returns the index of the first character that is non-numeric. the ord function will return the ascii decimal number of a character (see http://www.asciitable.com for a reference chart)
Then once you have that you can simply copy our the parts you need
Then once you have that you can simply copy our the parts you need
procedure TForm1.FormActivate(Sender : TObject);
var
S: String;
S1: String; //numer
S2: String; //alpha
I: Integer;
begin
S1:= '';
S2:= '';
S:= '234234some describtion.txt';
for I:= 1 to Length(S) do
if S[I] in ['0','1','2','3','4','5',' 6','7','8' ,'9'] then
S1:= S1 + S[I]
else
begin
S2:= Copy(S,I,Length(S));
Break;
end;
ShowMessage(S + #10#13 + S1 + #10#13 + S2);
end;
var
S: String;
S1: String; //numer
S2: String; //alpha
I: Integer;
begin
S1:= '';
S2:= '';
S:= '234234some describtion.txt';
for I:= 1 to Length(S) do
if S[I] in ['0','1','2','3','4','5','
S1:= S1 + S[I]
else
begin
S2:= Copy(S,I,Length(S));
Break;
end;
ShowMessage(S + #10#13 + S1 + #10#13 + S2);
end;
sorry, i did my testing in the Form's OnActivate event
You can just use this portion anywhere you like (Example: Button's OnCLick event)
Shane
var
S: String;
S1: String; //numer
S2: String; //alpha
I: Integer;
begin
S1:= '';
S2:= '';
S:= '234234some describtion.txt';
for I:= 1 to Length(S) do
if S[I] in ['0','1','2','3','4','5',' 6','7','8' ,'9'] then
S1:= S1 + S[I]
else
begin
S2:= Copy(S,I,Length(S));
Break;
end;
ShowMessage(S + #10#13 + S1 + #10#13 + S2);
end;
You can just use this portion anywhere you like (Example: Button's OnCLick event)
Shane
var
S: String;
S1: String; //numer
S2: String; //alpha
I: Integer;
begin
S1:= '';
S2:= '';
S:= '234234some describtion.txt';
for I:= 1 to Length(S) do
if S[I] in ['0','1','2','3','4','5','
S1:= S1 + S[I]
else
begin
S2:= Copy(S,I,Length(S));
Break;
end;
ShowMessage(S + #10#13 + S1 + #10#13 + S2);
end;
procedure TForm1.Button1Click(Sender : TObject);
var
strings : TStringList;
counter : Integer;
strLine : String;
varString : String;
varInteger : Integer;
linec : Integer;
begin
// create the string and load from file
strings := TStringList.Create;
strings.LoadFromFile('C:\t est.txt');
// loop through the strings
for counter := 0 to strings.Count - 1 do
begin
strLine := Strings[counter];
// pos indicates where digits start
linec := 0;
repeat
Inc(linec);
until (strLine[linec] in ['0'..'9']);
varString := Copy(strLine, 1, linec-1);
varInteger := StrToInt(Copy(strLine, linec, length(strLine) - linec + 1));
// add to string grid
StringGrid1.Cells[0, counter] := varString;
StringGrid1.Cells[1, counter] := IntToStr(varInteger);
end;
end;
var
strings : TStringList;
counter : Integer;
strLine : String;
varString : String;
varInteger : Integer;
linec : Integer;
begin
// create the string and load from file
strings := TStringList.Create;
strings.LoadFromFile('C:\t
// loop through the strings
for counter := 0 to strings.Count - 1 do
begin
strLine := Strings[counter];
// pos indicates where digits start
linec := 0;
repeat
Inc(linec);
until (strLine[linec] in ['0'..'9']);
varString := Copy(strLine, 1, linec-1);
varInteger := StrToInt(Copy(strLine, linec, length(strLine) - linec + 1));
// add to string grid
StringGrid1.Cells[0, counter] := varString;
StringGrid1.Cells[1, counter] := IntToStr(varInteger);
end;
end;
function IsNumber(C: String): Boolean;
begin
result:=false;
if (Pos(C,'123456789')>0) then result:=true;
end;
function GetNumberStrfromTXTString( ThisString : String) : string;
var SubStr : String;
i,j : Integer;
begin
i:=1; // ignore #0
while ((IsNumber(ThisString[i])= true) and (i<=length(ThisString))) do
begin
inc(i);
SubStr := Copy(ThisString,1 ,i-1);
end;
result:= SubStr;
end;
procedure TForm1.Button3Click(Sender : TObject);
begin
Edit7.Text := GetNumberStrfromTXTString( Edit8.Text );
end;
many, many ways to solve this problem ... .-)
begin
result:=false;
if (Pos(C,'123456789')>0) then result:=true;
end;
function GetNumberStrfromTXTString(
var SubStr : String;
i,j : Integer;
begin
i:=1; // ignore #0
while ((IsNumber(ThisString[i])=
begin
inc(i);
SubStr := Copy(ThisString,1 ,i-1);
end;
result:= SubStr;
end;
procedure TForm1.Button3Click(Sender
begin
Edit7.Text := GetNumberStrfromTXTString(
end;
many, many ways to solve this problem ... .-)
ASKER
shaneholmes is the closest one, Im just trying to change it so I would pass it a string with '234234some describtion.txt' and it would return me an array (TStrings) S1[0] would be the string and s1[2] would be the rest... how would I set a return value to be tstrings?
Tom
Tom
function IsNumber(C: String): Boolean;
begin
result:=false;
if (Pos(C,'123456789')>0) then result:=true;
end;
function GetTextStrfromTXTString(Th isString: String) : string;
var SubStr : String;
i,j : Integer;
begin
i:=1; // ignore #0
while ((IsNumber(ThisString[i])= true) and (i<=length(ThisString))) do
begin
inc(i);
// If you want to get the rest , just edit here ... ->
SubStr := Copy(ThisString,i ,length(ThisString)-i-1);
end;
result:= SubStr;
end;
begin
result:=false;
if (Pos(C,'123456789')>0) then result:=true;
end;
function GetTextStrfromTXTString(Th
var SubStr : String;
i,j : Integer;
begin
i:=1; // ignore #0
while ((IsNumber(ThisString[i])=
begin
inc(i);
// If you want to get the rest , just edit here ... ->
SubStr := Copy(ThisString,i ,length(ThisString)-i-1);
end;
result:= SubStr;
end;
well a just from head function
function GetNumber(AStr : String) : String;
var i : integer;
begin
result := '';
if AStr <> '' then
begin
i := 1;
while i < length(AStr) and (Astr[i] in ['0'..'9']) do inc(i);
result := copy(AStr,1,i-1);
end;
end;
meikl ;-)
function GetNumber(AStr : String) : String;
var i : integer;
begin
result := '';
if AStr <> '' then
begin
i := 1;
while i < length(AStr) and (Astr[i] in ['0'..'9']) do inc(i);
result := copy(AStr,1,i-1);
end;
end;
meikl ;-)
>it would return me an array (TStrings) S1[0] would be the string and s1[2]
another solution
function GetNumber(var AStr : String) : String;
var i : integer;
begin
result := '';
if AStr <> '' then
begin
i := 1;
while i < length(AStr) and (Astr[i] in ['0'..'9']) do inc(i);
result := copy(AStr,1,i-1);
ASTr := copy(AStr,i,maxlongint);
end;
end;
--> returns the number
--> AStr holds now only the rest (Number excluded)
just not tested
meikl ;-)
another solution
function GetNumber(var AStr : String) : String;
var i : integer;
begin
result := '';
if AStr <> '' then
begin
i := 1;
while i < length(AStr) and (Astr[i] in ['0'..'9']) do inc(i);
result := copy(AStr,1,i-1);
ASTr := copy(AStr,i,maxlongint);
end;
end;
--> returns the number
--> AStr holds now only the rest (Number excluded)
just not tested
meikl ;-)
Something like this?
function FirstLetterInString(s:Stri ng):intege r;
var x:Integer;
begin
//Returns the index of the first letter in a string;
Result := 0;
for x:=1 to length(s) do
if ((ord(s[x]) < 48) or (ord(s[x]) > 57)) then
begin
Result := x;
break;
end;
end;
procedure SeperateString(s:String; var slist:TStringList);
var idx:Integer;
firstpart,secondpart:Strin g;
begin
idx := FirstLetterInString(s);
if idx > 0 then
begin
sList.Add(Copy(s,1,idx -1));
sList.Add(copy(s,idx,lengt h(s)));
end;
end;
procedure TForm1.Button1Click(Sender : TObject);
var idx:Integer;
slist:TStringList;
s:String;
begin
s := '234234some';
sList := TStringList.Create;
try
SeperateString(s,slist);
ShowMessage(sList[0]);
ShowMessage(sList[1]);
finally
slist.free;
end;
end;
function FirstLetterInString(s:Stri
var x:Integer;
begin
//Returns the index of the first letter in a string;
Result := 0;
for x:=1 to length(s) do
if ((ord(s[x]) < 48) or (ord(s[x]) > 57)) then
begin
Result := x;
break;
end;
end;
procedure SeperateString(s:String; var slist:TStringList);
var idx:Integer;
firstpart,secondpart:Strin
begin
idx := FirstLetterInString(s);
if idx > 0 then
begin
sList.Add(Copy(s,1,idx -1));
sList.Add(copy(s,idx,lengt
end;
end;
procedure TForm1.Button1Click(Sender
var idx:Integer;
slist:TStringList;
s:String;
begin
s := '234234some';
sList := TStringList.Create;
try
SeperateString(s,slist);
ShowMessage(sList[0]);
ShowMessage(sList[1]);
finally
slist.free;
end;
end;
oops.. you can remove the variables "firstpart" and "secondpart" from SeperateString
ASKER
while i < length(AStr) and (Astr[i] in ['0'..'9']) do inc(i);
it shows "opperator is not applicable to this operand type"
it shows "opperator is not applicable to this operand type"
>while i < length(AStr) and (Astr[i] in ['0'..'9']) do inc(i);
missed some brackets
while (i < length(AStr)) and (Astr[i] in ['0'..'9']) do inc(i);
should work now
meikl ;-)
missed some brackets
while (i < length(AStr)) and (Astr[i] in ['0'..'9']) do inc(i);
should work now
meikl ;-)
Is there something wrong with my code? Have you tried it? Is it not what you asked for?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
function GetMain(var AStr : String) : String;
var i : integer;
begin
result := '';
if AStr <> '' then
begin
i := 1;
while (i <= length(AStr)) and (Astr[i] = '.') do inc(i);
result := copy(AStr,1,i-1);
ASTr := copy(AStr,i,maxlongint);
end;
end;
I just changed it to split by the '.' character to return the main part of the filename ( without the .txt ) why doesnt it work?
Ps meikl gets the points his example worked great and I can understand it :)
Tom
var i : integer;
begin
result := '';
if AStr <> '' then
begin
i := 1;
while (i <= length(AStr)) and (Astr[i] = '.') do inc(i);
result := copy(AStr,1,i-1);
ASTr := copy(AStr,i,maxlongint);
end;
end;
I just changed it to split by the '.' character to return the main part of the filename ( without the .txt ) why doesnt it work?
Ps meikl gets the points his example worked great and I can understand it :)
Tom
>I just changed it to split by the '.' character to return the main part of the filename ( without the .txt )
>why doesnt it work?
because this loop
while (i <= length(AStr)) and (Astr[i] = '.') do inc(i);
ends if the first char is no '.'
just change it to
while (i <= length(AStr)) and (Astr[i] <> '.') do inc(i);
and it should work (not tested yet)
glad you like my solution :-)
(but the others may work also, i guess)
meikl ;-)
>why doesnt it work?
because this loop
while (i <= length(AStr)) and (Astr[i] = '.') do inc(i);
ends if the first char is no '.'
just change it to
while (i <= length(AStr)) and (Astr[i] <> '.') do inc(i);
and it should work (not tested yet)
glad you like my solution :-)
(but the others may work also, i guess)
meikl ;-)
hmm, your orginal question said nothing about an array ......
Dont you think a split would have been warranted - at a minimum?
<SMILE>
Shane
Dont you think a split would have been warranted - at a minimum?
<SMILE>
Shane
right. both of my solutions did exactly what you asked for. even though you changed your requirements half way through it
var x:Integer;
begin
//Returns the index of the first letter in a string;
Result := 0;
for x:=1 to length(s) do
if ((ord(s[x]) < 48) or (ord(s[x]) > 57)) then
begin
Result := x;
break;
end;
end;
procedure TForm1.Button1Click(Sender
var idx:Integer;
s,firstpart,secondpart:Str
begin
s := '234234some';
idx := FirstLetterInString(s);
if idx > 0 then
begin
firstpart := Copy(s,1,idx -1);
secondpart := copy(s,idx,length(s));
ShowMessage('First Part = '+FirstPart);
ShowMessage('Second Part = '+SecondPart);
end
else
showmessage('Error');
end;