antomatskev
antomatskev

Reputation: 63

Kotlin: check if string is numeric

Is there a simple way to check if user's input is numeric? Using regexes and exceptions seems too complicated here.

fun main {
    val scan = Scanner(System.`in`)
    val input = scanner.nextLine()
    if (!input.isNumeric) {
        println("You should enter a number!")
    }
}

Upvotes: 6

Views: 9682

Answers (6)

mightyandweakcoder
mightyandweakcoder

Reputation: 844

A simple answer without any custom functions is to utilise toDoubleOrNull function. If it returns null, the string is not numeric.

val string = "-12345.666"
if (string.toDoubleOrNull()!=null) // string is numeric
{
  //do something
}

If you know the input only contains integers you can also use toIntOrNull likewise

Upvotes: 0

MDT
MDT

Reputation: 1695

Well all the answers here are best suited for their own scenarios: But not all string are numeric digits it can have (-) and (.) decimal pointers.

So to accomplish this I made a cocktail of all the answers suggested below and from other posts as well which - looks like below :

fun isPosOrNegNumber(s: String?) : Boolean {
    return if (s.isNullOrEmpty()) false 
    else{
        if(s.first()=='-' && s.filter { it == '.' }.count() <= 1) {
            s.removeRange(0,1).replace(".","").all{Character.isDigit(it)}
        }
        else s.all {Character.isDigit(it)}
    }
}

Above code does a good job for its purpose. But then it struck me kotlin does an even better job with matching a regex and voila the solution became simple and elegant as below :

fun isPosOrNegNumber(s: String?) : Boolean {
    val regex = """^(-)?[0-9]{0,}((\.){1}[0-9]{1,}){0,1}$""".toRegex()
    return if (s.isNullOrEmpty()) false 
           else regex.matches(s)
        
}

This sample regex is only for US number formats but if you want to use EU number formats then just replace '.' with ','

Bdw. if the numbers contain commas then just replace it while sending to this method or better form a regex pattern with commas in it.

enter image description here

Upvotes: 1

Pranav Choudhary
Pranav Choudhary

Reputation: 2806

Another way to check if the given string is numeric( to check for both negative and positive values ) or not:

val intChars =  '0'..'9'


fun isNumeric(input: String) = input
    .removePrefix("-")
    .all { it in '0'..'9' }

Upvotes: 0

Iman Marashi
Iman Marashi

Reputation: 5753

Simply use : text.isDigitsOnly() in kotlin.

Upvotes: 8

Animesh Sahu
Animesh Sahu

Reputation: 8106

The method mentioned above will work for a number <= approximately 4*10^18 essentially max limit of Double.

Instead of doing that since String itself is a CharSequence, you can check if all the character belong to a specific range.

val integerChars = '0'..'9'

fun isNumber(input: String): Boolean {
    var dotOccurred = 0
    return input.all { it in integerChars || it == '.' && dotOccurred++ < 1 }
}

fun isInteger(input: String) = input.all { it in integerChars }

fun main() {
    val input = readLine()!!
    println("isNumber: ${isNumber(input)}")
    println("isInteger: ${isInteger(input)}")
}

Examples:

100234
isNumber: true
isInteger: true

235.22
isNumber: true
isInteger: false

102948012120948129049012849102841209849018
isNumber: true
isInteger: true

a
isNumber: false
isInteger: false

Its efficient as well, there's no memory allocations and returns as soon as any non-satisfying condition is found.

You can also include check for negative numbers by just changing the logic if hyphen is first letter you can apply the condition for subSequence(1, length) skipping the first character.

Upvotes: 10

Ben Shmuel
Ben Shmuel

Reputation: 2009

joining all the useful comments and putting it in a input stream context, you can use this for example:

fun readLn() = readLine()!!
fun readNumericOnly() {
    println("Enter a number")
    readLn().toDoubleOrNull()?.let { userInputAsDouble ->
        println("user input as a Double $userInputAsDouble")
        println("user input as an Int ${userInputAsDouble.toInt()}")
    } ?: print("Not a number")


}
readNumericOnly()

for input: 10

user input as a Double 10.0 
user input as an Int 10

for input: 0.1

user input as a Double 0.1 
user input as an Int 0 

for input: "word"

Not a number

Upvotes: 6

Related Questions