Android Question Estrapolate ints from a string

FreeWolF

Active Member
Licensed User
Longtime User
Hello, there is a method for estrapolate an int from a text?

For Example:

B4X:
dim a as int
dim b as string


b = "Hello, I have 3 dogs"

I want to set the "dim a" to 3 (the ONLY number in the string).

Any ideas?

Thanks in advance!
 

IlCasti

Active Member
Licensed User
Longtime User
i'm not in front of b4a so try
using stringfunctions something like

B4X:
a=""
for i = 1 to len(b)
if isnumeric(mid(b,i,1)) then
  a= mid(b,i,1) 'a = a & mid(b,i,1) this for more numbers
end if
next

bye

IlCasti
 
Upvote 0

James Chamblin

Active Member
Licensed User
Longtime User
this works
B4X:
Sub ExtractNumber (a As String) As String
   Dim result As String
   Dim digit As Boolean = False
   Dim decimal As Boolean = False
   Dim i As Int
   
   For i = 0 To a.Length - 1
     If "0123456789".Contains(a.CharAt(i)) = True Then 'we found a digit
       digit = True
       result = result & a.CharAt(i)
     Else If digit = True AND a.CharAt(i) = "." AND decimal = False Then 'we found the decimal point
       decimal = True
       result = result & a.CharAt(i)
     Else If digit = True Then'no digit found, end of number
       Exit
     End If
     'no number has been found yet, go to the next character
   Next
   Return result
End Sub
It will not work properly with negative numbers, -123 will return 123, and any number < 0 must have a leading 0, .123 will return 123, but 0.123 will return 0.123.
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
This works too:
B4X:
Sub GetNumber(txt As String) As Int
    Dim c() As String
    Dim i As Int
   
    c = Regex.Split(" ", txt)
    For i = 0 To c.Length - 1
        If IsNumber(c(i)) Then
            Exit
        End If
    Next
   
    If i < c.Length Then
        Return c(i)
    Else
        ToastMessageShow("No number", False)
    End If
End Sub
Call it with :
B4X:
Dim a As Int
a = GetNumber("Hello, I have -1 dogs")
It returns only the first number.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
I want to make myself agreeable.:rolleyes:

The solution of James does not work when the decimal points and commas for the thousands are reversed, as here in Italy. It will be sufficient to use string variables for these characters.

The solution of Klaus will not work if the number is next to characters that are not spaces.

(I'm a troublemakers, I know :D)
 
Upvote 0

IlCasti

Active Member
Licensed User
Longtime User
Klaus you cannot have -1 dog. o_O
Maybe James can have 0.123 dog (something like a chihuahua) :rolleyes:
Mine, if it works, is the best one LOL ;)
Luca you're right, you are troublemakers :D:D:D
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
My solution is... damn, i must change my Avatar, sorry :D

Done.
__________________________________________________

My "solution":

I do not know Regex (Erel is an expert), but I think we can estropolare groups using it.
I leave this to the alien :D

Or, using some variables for comma and dot, run the cycle as IlCasti has done, and using vars like NumStartPos NumEndPos, etc..

Ok, I try to write it ... but I would prefer the intervention of an expert in Regex
 
Last edited:
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
B4X:
    Private lstNum As List : lstNum.Initialize
   
    Private Text As String
    Text = "FreeWolf has 3 dogs, 2 wolfs --> ,5.5 million dollars but live in a city where the temperature is always between -15°"
   
    lstNum = NumsFromString(Text)
   
    For I = 0 To lstNum.Size - 1
        Log(lstNum.Get(I))
    Next

B4X:
Private Sub NumsFromString(Text As String) As List
    Private lstResult As List : lstResult.Initialize
   
    Private ValidChars As String = "-+0123456789.,"

    Private NumStartPos, ValidCharPos As Int
    Private Ch, Num As String
    NumStartPos = -1
    Num = ""
    For c = 0 To Text.Length - 1
        Ch = Text.SubString2(c, c + 1)
        ValidCharPos = ValidChars.IndexOf(Ch)
        If ValidCharPos >= 0 Then
            If NumStartPos >= 0 Then
                Num = Num & Ch
            Else
                NumStartPos = c
                Num = Num & Ch
            End If
        Else
            If Num <> "" Then
                If IsNumber(Num) Then
                    lstResult.Add(Num)
                End If
                Num = ""
            End If
            NumStartPos = -1
        End If
    Next
   
    If Num <> "" Then
        If IsNumber(Num) Then
            lstResult.Add(Num)
        End If
    End If
   
    Return lstResult
   
End Sub
 
Upvote 0

FreeWolF

Active Member
Licensed User
Longtime User
Thanks a lot LucaMS :) I will try your code too! But I have tried also the other codes and run. But sometimes the value I return is 0....
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
I tried to write code that is also suitable for other types of sentences.

The code that they have proposed works for the phrase that you have proposed.

You could also solve giving away the 3 dogs, so the sentence would be:
"I do not have dogs" and you would not need functions :D
(Warning: Do not use "I had 3 dogs")
 
Upvote 0

James Chamblin

Active Member
Licensed User
Longtime User
This makes better use of RegEx
B4X:
  Dim a As String = "I have 3 dogs, 1.5 pigs (ate half of one already), and -.75 chickens (one of my dogs ate the neighbors lunch after he only ate a quarter of his chicken, so now I owe him the rest of his lunch)."
   Dim m As Matcher
  
   m = Regex.Matcher("[+-]?(\d+\.?\d*|\.\d+)",a)
   Do While m.Find
     Log("Number = " & m.Match)
   Loop
Wrote my response while MaFu was writing his.:)
 
Upvote 0
Top