Delphi extract numbers from string
Solution 1
I think this function is what you are looking for:
function ExtractNumbers(const s: string): TArray<string>;
var
i, ItemIndex: Integer;
LastCharWasDigit: Boolean;
len: Integer;
Count: Integer;
Start: Integer;
begin
len := Length(s);
if len=0 then begin
Result := nil;
exit;
end;
Count := 0;
LastCharWasDigit := False;
for i := 1 to len do begin
if TCharacter.IsDigit(s[i]) then begin
LastCharWasDigit := True;
end else if LastCharWasDigit then begin
inc(Count);
LastCharWasDigit := False;
end;
end;
if LastCharWasDigit then begin
inc(Count);
end;
SetLength(Result, Count);
ItemIndex := 0;
Start := 0;
for i := 1 to len do begin
if TCharacter.IsDigit(s[i]) then begin
if Start=0 then begin
Start := i;
end;
end else begin
if Start<>0 then begin
Result[ItemIndex] := Copy(s, Start, i-Start);
inc(ItemIndex);
Start := 0;
end;
end;
end;
if Start<>0 then begin
Result[ItemIndex] := Copy(s, Start, len);
end;
end;
Solution 2
If you have Delphi XE or up, you can use regular expressions. This is completely untested, based on David Heffernan's answer:
function ExtractNumbers(const s: string): TArray<string>;
var
regex: TRegEx;
match: TMatch;
matches: TMatchCollection;
i: Integer;
begin
Result := nil;
i := 0;
regex := TRegEx.Create("\d+");
matches := regex.Matches(s);
if matches.Count > 0 then
begin
SetLength(Result, matches.Count);
for match in matches do
begin
Result[i] := match.Value;
Inc(i);
end;
end;
end;
Solution 3
function ExtractNumberInString ( sChaine: String ): String ;
var
i: Integer ;
begin
Result := '' ;
for i := 1 to length( sChaine ) do
begin
if sChaine[ i ] in ['0'..'9'] then
Result := Result + sChaine[ i ] ;
end ;
end ;
Solution 4
inspired by user2029909 response
function ExtractNumberInString (sChaine: String; Start : Integer = 1): TArray<String> ;
var
i, j: Integer ;
TmpStr : string;
begin
j := 0;
for i := Start to Length( sChaine ) do
begin
if sChaine[ i ] in ['0'..'9'] then
TmpStr := TmpStr + sChaine[ i ]
else
if TmpStr <> '' then
begin
SetLength(Result, Length(Result) + 1);
Result[j] := TmpStr;
TmpStr := '';
Inc(j);
end;
end ;
end ;
colin
Updated on June 07, 2022Comments
-
colin almost 2 years
I have a variety of strings which I need to work with, these contain both letters and numbers , I am trying to extract the numbers (which is the part I need) from the string, the strings would have a similar format to -
the cat can count 123 567 so can the dog"
The length and position of the numbers can vary from 12 34 123 456 1234 5678 11111 11111
Also the number seperator can vary from a space question mark and also a dash 12-34 12.34 So the string could be EG “the cat can't count, the dog can 12-67” or “the cat can count 1234.5678 so can the dog” Is there any clever way in Delphi I can extract the numbers? Or would I have to do it by scanning the string in code.
Any help would be appreciated
Thanks
colin
-
Marjan Venema over 12 years+1 nice way of returning all individual numeric parts. Would hate to have to add support for returning
123.12
as a single numeric part though, especially when takinga.123
,a. .123
and123. 456
or123 .456
etc. into consideration. :) -
David Heffernan over 12 years@Marjan And there's always negative numbers, but OP does appear to regard any non-digit as a sep.
-
colin over 12 years@David Thanks that does the job
-
David Heffernan over 12 years+1 I prefer this to my version. That said if Matches.Count does not compile.
-
David Heffernan almost 5 years@SHINJaeGuk This happened in the 7 years that have elapsed since the answer was written. Now you use the record helper for
Char
and writes[i].IsDigit
. -
LU RD almost 3 yearsThere can be multiple numbers in the string, so this answer does not answer the question.
-
LU RD almost 3 yearsThere can be multiple numbers in the string, so this answer does not answer the question. Also, all numbers are positive integers.
-
SpeedResolve almost 3 years@LU RD I can post another function I built where a series of floating point numbers is recognized and listed in a dynamic array. The function above will identify the first floating point number from the position Start on, and mark its end at Last, giving a string compatible with a subsequent StrToFloat input, if the string is different from nil.
-
LU RD almost 3 yearsThe question is not about floating point numbers. Anything but 0..9 should be treated as space.
-
SpeedResolve almost 3 yearsWell, you are not wrong, but I think the code I gave may help in that regard. I searched for similar subjects here in stack and didn't find this problem in Delphi. So I made it myself. It may not be the optimal place to share it, but there you go
-
Akin Okegbile over 2 yearsCan you add more commentary on this code?
-
Admin over 2 yearsPlease add further details to expand on your answer, such as working code or documentation citations.