Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if and what type of number a string represents?

How can I check whether a string represents a long, a double, or just a regular string? I need to do this because this value needs to be indexed in a database according to its type. Currently I'm doing this by trying to parse the string and checking for exceptions but since the code is called very frequently, I'm wondering if there's a more efficient way to do it. My code currently looks like this:

String value = ...;
// For example, could be "213678", "654.1236781", or "qwerty12345"

try {
    Long longValue = Long.parseLong(value);
    // Index 'longValue' in the database
} catch (NumberFormatException parseLongException) {
    try {
        Double doubleValue = Double.parseDouble(value);
        // Index 'doubleValue' in the database
    } catch (NumberFormatException parseDoubleException) {
        // Index 'value' in the database
    }
}

EDIT:

I just did a quick benchmarking exercise as per @user949300's suggestion to use regex patterns and it performed slightly better than the exception handling code above. Here's the code in case someone else finds it useful:

Pattern longPattern = Pattern.compile("^[-+]?[0-9]+$");
Pattern doublePattern = Pattern.compile("^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?$");

// Check for long regex pattern before the double regex pattern
// since the former is a strict subset of the latter
if (longPattern.matcher(value).matches()) {
    // Perform indexing for long in the database
} else if (doublePattern.matcher(value).matches()) {
    // Perform indexing for double in the database
} else {
    // Perform indexing for string in the database
}

Here are the benchmarking results for checking 50,000 entries where the approximate breakdown of types is 50% longs, 10% doubles, 40% strings (representative of the workload that my application processes):

--- Exception handling code ---
STRING - actual: 19861, found: 19861
DOUBLE - actual: 4942, found: 4942
LONG - actual: 25197, found: 25197
Time taken: 2561 ms

--- Regex pattern matching code ---
STRING - actual: 19861, found: 19861
DOUBLE - actual: 4942, found: 4942
LONG - actual: 25197, found: 25197
Time taken: 1565 ms
like image 916
Dawood Avatar asked Jan 27 '12 23:01

Dawood


People also ask

How do you test if a value is a string?

To check if a variable contains a value that is a string, use the isinstance built-in function. The isinstance function takes two arguments. The first is your variable. The second is the type you want to check for.

How do you check if a string is an integer or int?

Checking If Given or Input String is Integer or Not Using isnumeric Function. Python's isnumeric() function can be used to test whether a string is an integer or not. The isnumeric() is a builtin function. It returns True if all the characters are numeric, otherwise False.

How do you check a string is a number in Python?

Python String isnumeric() Method The isnumeric() method returns True if all the characters are numeric (0-9), otherwise False. Exponents, like ² and ¾ are also considered to be numeric values. "-1" and "1.5" are NOT considered numeric values, because all the characters in the string must be numeric, and the - and the .

How do you check if an element in a string is an integer?

Using built-in method isdigit(), each character of string is checked. If the string character is a number, it will print that string contains int. If string contains character or alphabet, it will print that string does not contain int.


2 Answers

Have you considered regular expressions?

If the String contains anything other than - (at the beginning), and 0-9 or ., it is a String. (Note - this ignores internationalization and scientific notation - are they issues?)

Otherwise, it it contains a ., it is a double. (Well, you should test for only a single ., but this is a start)

Otherwise, it is a long.

Out of paranoia, I still might check for Exceptions, but that might be a faster way.

NOTE ADDED I'm guessing that testing the regex is faster than throwing exceptions out of the various parse routines, but this might not actually be true. You should do some tests.

like image 170
user949300 Avatar answered Oct 18 '22 17:10

user949300


As far as I know there's no elegant way to do this other than that. I would recommend that you parse them in the order of most common to least common so as to make this as quick as possible.

If you've got more than 3 possible types you're going to have a deep and ugly try-catch nest, but technically it will be faster than if you broke out each parse attempt into its own method; the tradeoff here is whether you want code clarity or faster execution - it sounds like you might want the latter.

like image 43
Nate W. Avatar answered Oct 18 '22 19:10

Nate W.