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.
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")
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.
Klaus you cannot have -1 dog.
Maybe James can have 0.123 dog (something like a chihuahua)
Mine, if it works, is the best one LOL
Luca you're right, you are troublemakers
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
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
(Warning: Do not use "I had 3 dogs")
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