Win a copy of Five Lines of Code this week in the OO, Patterns, UML and Refactoring forum!
    Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Bear Bibeault
  • Ron McLeod
  • Jeanne Boyarsky
  • Paul Clapham
Sheriffs:
  • Tim Cooke
  • Liutauras Vilda
  • Junilu Lacar
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • fred rosenberger
  • salvin francis
Bartenders:
  • Piet Souris
  • Frits Walraven
  • Carey Brown

How to check if String() value is numeric

 
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
  • Report post to moderator
Hello,

I have a situation where I want to validate whether the value passed in as a String() is a numeric v. alpha/special char value. The process that will consume this data post-validation will be expecting numeric values.

Can someone give me a hint with how to do this without using a NumberFormatException? If the Exception is encountered the only recovery necessary will be to log the data that needs to be reviewed since the data is subjective and cannot be modified at runtime based on any conditions. I could just try to catch a NFE when trying to convert the value to an integer and then log that that data needs to be eye-balled, but I was hoping to do something a little more purdy.

If I were to use the java regex uitils, would I be provided a means to eliminate all alpha and special characters?

Just looking for a thums-up/thumbs-down or a possible alternative.

Thanks!

bo-bizzle po-pizzle
 
Marshal
Posts: 69782
277
  • Mark post as helpful
  • send pies
  • Report post to moderator
Hello.
I'm afraid I am not too familiar with regular expressions, which might be a better option than this:
BUT
How about changing your String to a char[] (String.toCharArray()) and then using the Character.isDigit() method?

OR: You could iterate along the string and try String.charAt(i).isDigit();

Anybody suggest a better way with a regular expression?
 
Ranch Hand
Posts: 4632
  • Mark post as helpful
  • send pies
  • Report post to moderator
a lot depends on your definition of numeric - integer, double etc

you could use
Integer.parseInt()
Double.parseDouble()
and catch the exception

you could use (if numeric = integer)
if(stringNumber.replaceAll("\\d+","").length() > 0) [fails]
 
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
  • Report post to moderator
The parse and catch exception solution is not too bad. If you handle thousands of these while a user is waiting and you think 99% will be bad you might be concerned about performance, but otherwise I'd take the hit. You can do a lot studying each digit or matching expressions but it's a lot of effort to accept every valid int and reject every invalid one, and even more work for floating types. You can make a short method like this:

and be done.
 
Bob Robertson
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
  • Report post to moderator
Ok, I agree that the try/catch method would be the easiest and it is funny that someone mentioned that accounting for floats would add to the hassle. Turns out, all the valid integers I need are actually being stored as floats which invalidates everything.

For example, I am using POI to parse an excel doc. When I grab the data from a column where I expect the data to be a cell type of numeric, I actually get a float represenation of the value (e.g. 12 becomes 12.0 through POI's API).

When I test that value using the regex API pattern [0-9]* it fails because the value is a float. But floats should fail because 12.5 would be an invalid value.

So now once I get this value as a String(), I have to do the following:

1- Remove all whitespace
2- Test for non-numeric values
3- Somehow make sure that the value after the decimal is always a 0.

Regex may get me where I need if I can figure out a pattern that accepts decimals points, but only allows that value after the decimal to be a 0. Otherwise, I guess I could try/catch on a parseFloat() and figure out some logic to test the value after the decimal, right?
 
Bob Robertson
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
  • Report post to moderator
Ok, so here is what I tried... I'm really starting to like the regex API, by the way. Going to have to read up more on how to use them patterns!

String a = "12.0"; //Valid
String b = "12.5"; //Invalid

Pattern p = Pattern.compile( "([0-9]*)\\.[0]" );

Matcher m = p.matcher(a);
m.matches(); //TRUE

Matcher m = p.matcher(b);
m.matches(); //FALSE

I think this will be me over the hump unless anyone can predict some scenarios where I may miss some data. I'd appreciate any comments.

Thanks!!!

br
 
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
  • Report post to moderator
I think you've got it right. I have one word of caution, though: escape characters. I believe you are familiar with escape characters in Java such as '\n' for newline and '\\' for a literal backslash. Regular expressions also use escape characters because some characters like '.' have special meaning. So if you want a literal '.', you have to escape it as "\.". Of course, you already know this since you seem to have written the regex to take this into account.

This becomes a problem because Java sees the regex as a String before it passes it on to the regex library. This means that you typically have to add extra backslashes to escape it enough. For example, to make a regex for a literal backslash, you need FOUR of them! This is because "\\" stands for a literal backslash to the regex library. But to get two backslashes in a Java String, you need to escape both of them, as in "\\\\".

I don't think this is a problem in your particular situation. I'm just bringing it up as something to look out for in case it doesn't work the way you expect. It's also something to be aware of if you continue to use regexes in future projects.

Layne
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
  • Report post to moderator
If you're using JDK 5 (and if not, why not?) you can use a Scanner instead, which gives you access to ready-made methods which parse numbers of various types (including boolean test methods which allow you to avoid exceptions if that's a problem):

[ October 18, 2005: Message edited by: Jim Yingst ]
 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Report post to moderator
just fyi, the above method is missing an 'e' after catch(Exception e):


 
Campbell Ritchie
Marshal
Posts: 69782
277
  • Mark post as helpful
  • send pies
  • Report post to moderator
Welcome to the Ranch

You did realise that was a 4-year old post?
 
Andrew Dondero
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Report post to moderator
sure, but that shouldn't preclude fixing the mistake. This thread was a number 1 hit on google on this topic, so other people searching for this same thing would no doubt copy the code and find the compile error. i was looking to see if there was a more elegant solution, but ended up doing the simple try/catch. to save time I just copied the code rather than retype, and this small error caused a bit of frustration, because the tool we are using does not have an IDE like eclipse that will tell you in real time where and what the compile error is.
 
Campbell Ritchie
Marshal
Posts: 69782
277
  • Mark post as helpful
  • send pies
  • Report post to moderator
Thank you. I am splitting this thread.
 
    Bookmark Topic Watch Topic
  • New Topic