I am given a string that can include both text and numeric data:
Examples:
"100 pounds" "I think 173 lbs" "73 lbs."
I am looking for a clean way to extract only the numeric data from these strings.
Here is what I'm currently doing to strip the response:
def stripResponse(String response) {
if(response) {
def toRemove = ["lbs.", "lbs", "pounds.", "pounds", " "]
def toMod = response
for(remove in toRemove) {
toMod = toMod?.replaceAll(remove, "")
}
return toMod
}
}
You could use findAll
then convert the results into Integers:
def extractInts( String input ) {
input.findAll( /\d+/ )*.toInteger()
}
assert extractInts( "100 pounds is 23" ) == [ 100, 23 ]
assert extractInts( "I think 173 lbs" ) == [ 173 ]
assert extractInts( "73 lbs." ) == [ 73 ]
assert extractInts( "No numbers here" ) == []
assert extractInts( "23.5 only ints" ) == [ 23, 5 ]
assert extractInts( "positive only -13" ) == [ 13 ]
If you need decimals and negative numbers, you might use a more complex regex:
def extractInts( String input ) {
input.findAll( /-?\d+\.\d*|-?\d*\.\d+|-?\d+/ )*.toDouble()
}
assert extractInts( "100 pounds is 23" ) == [ 100, 23 ]
assert extractInts( "I think 173 lbs" ) == [ 173 ]
assert extractInts( "73 lbs." ) == [ 73 ]
assert extractInts( "No numbers here" ) == []
assert extractInts( "23.5 handles float" ) == [ 23.5 ]
assert extractInts( "and negatives -13" ) == [ -13 ]
Solution that I ended up implementing based on advice above, I only want to grab the first number (if there are multiples I invalidate the response). Thanks @tim_yates !
def extractNumericData(String response) { if(response) { def numberList = response.findAll( /[0-9]+.[0-9]*|[0-9]*.[0-9]+|[0-9]+/ ) if(numberList.size() == 1) { return numberList.get(0) as BigDecimal } else { return -1 } } }
For some reason I get this:
java.lang.UnsupportedOperationException: spread not yet supported in input.findAll(\d+)*.toInteger()
. ---- And it says on Jenkins its resolved.