• Post Reply 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 Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

How to check if String() value is numeric

 
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • 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: 79151
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • 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
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • 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
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • 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
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • 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
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • 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
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • 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
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • 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
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
just fyi, the above method is missing an 'e' after catch(Exception e):


 
Greenhorn
Posts: 1
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I also got to this page from a top hit in google.

I use the following regex to check whether a string is numeric or not.

((-|\\+)?[0-9]+(\\.[0-9]+)?)+

Valid:
4324
+4123
12321.43
-123.432432
100.00

Invalid:
3243.
32 3232
1231.32131.333
-
+-1232134.12
Any text

Example:
 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I also got here from google. Good pattern but needs an update.

Tried to extend it so only one or two decimal places are accepted [0-9]{1,2}+ , and it didnt work. So I had to rewrite it from scratch.
In your pattern the last greedy quantifier (X)+ should be removed since it causing that strings like 1231.32131.333 are accepted.

So finally it should be: (-|\\+)?[0-9]+(\\.[0-9]+)?
and in case of limitimg decimal places (-|\\+)?[0-9]+(\\.[0-9]{1,2}+)?
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Andrzej Lach wrote:I also got here from google. Good pattern but needs an update.


Erm, you've just revived a 2-year old Thread that itself was a revival of a 7-year old one.

Are you trying for some kind of record?

Winston
 
Andrzej Lach
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Of course I am not going for a record:) and was not looking at dates.
Since it is still in the top of google search, wasn't closed thread and I found an issue I wanted to correct it...
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks and welcome to CodeRanch!
 
Greenhorn
Posts: 1
Eclipse IDE Tomcat Server Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Your easiest solution would be to use Integer.parseInt() on the string and catch the exception if it is not a number.
 
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Can you use external libraries? if you can then get the Apache commons lang jar.

http://commons.apache.org/lang/

download:
http://commons.apache.org/lang/download_lang.cgi

maven:
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>

Inside there is the StringUtils class which does what you need
http://commons.apache.org/lang/api-3.1/org/apache/commons/lang3/StringUtils.html

Its full of static methods to test and modify strings you will be amazed of how much stuff you can do with it.

 
Ranch Hand
Posts: 808
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Your easiest solution would be to use Integer.parseInt() on the string and catch the exception if it is not a number.


Lazy much? Exceptions are for telling you there is a problem in your application. Use the method posted by Campbell Ritchie seven years ago.
 
Master Rancher
Posts: 4796
72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Dennis Deems wrote:

Your easiest solution would be to use Integer.parseInt() on the string and catch the exception if it is not a number.


Lazy much? Exceptions are for telling you there is a problem in your application. Use the method posted by Campbell Ritchie seven years ago.


What, we're insulting people for using parseInt() now? That's a perfectly valid solution unless performance is an issue. Stan James, RIP, discussed it above years ago, and he's still right. I'm also fond of the Scanner solution suggested above, also years ago.
 
dennis deems
Ranch Hand
Posts: 808
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:

Dennis Deems wrote:

Your easiest solution would be to use Integer.parseInt() on the string and catch the exception if it is not a number.


Lazy much? Exceptions are for telling you there is a problem in your application. Use the method posted by Campbell Ritchie seven years ago.


What, we're insulting people for using parseInt() now? That's a perfectly valid solution unless performance is an issue. Stan James, RIP, discussed it above years ago, and he's still right. I'm also fond of the Scanner solution suggested above, also years ago.


You mean, do I truly think it's lazy deliberately to invoke a method in a spirit contrary to its clearly stated purpose just because you can slip a try/catch around the invocation and get what you want? Yes. Sorry that seems insulting; it isn't meant to be.
 
Mike Simmons
Master Rancher
Posts: 4796
72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hmmm, from my perspective your phrasing inspires several less-than-charitable replies which I'm omitting. I'll just say that what you call "lazy" may also be simple and direct (which I consider a virtue for readability and maintainability), making use of a standard library method in the only way it really supports. I don't agree with you at all about the purpose of the method - it clearly handles validity checking too, and the designers assumed that catching a specific exception was a valid option for the programmer. In my opinion, naturally.

Note also that the task is often not only to tell if a String is numeric, but also to do something with that number afterwards. In such cases it's not enough just to tell if the characters are digits - we also need to make sure that the result fits in the datatype we've chosen. And we need to actually convert the string to a number. In which case, Integer.parseInt() is tailor-made, and catching the NumberFormatException is the only option the library really provides.

Even if it's not necessary to convert the value to a number, parseXxx() methods are convenient ways to check validity. Convenience is a good thing. And what if the programmer needs to identify a valid double? The logic here becomes more complicated - is it really necessary for the programmer to reinvent the wheel here, just to avoid catching an exception? I think not.

(Remember, too, that regular expressions and Scanner came to Java much later than the parseXxx() methods did. Yeah, there are other ways to do this now, but for years, they didn't exist. Catching NumberFormatException was The Way to handle this problem.)

The religiously absolutist idea that exceptions can only be used to indicate errors in the application (as opposed to input data) can be pointlessly counterproductive, as not all libraries are actually designed this way.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:The religiously absolutist idea that exceptions can only be used to indicate errors in the application (as opposed to input data) can be pointlessly counterproductive, as not all libraries are actually designed this way.


Hmmm. Not sure I like the term "religiously absolutist" because, all other things being equal, I tend to agree with Dennis. If this was a file as opposed specifically to user input, I doubt you would be advocating this style, so at best it works in situations where you know that it's the only way you're going to receive numbers.

The advantage of a regex (or indeed Scanner) is that it can be applied to any InputStream, so if you're testing, you can change your mode of input; and if you wrap it in a decent utility method, who cares how complicated the actual code is?

Winston

 
Mike Simmons
Master Rancher
Posts: 4796
72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Winston Gutkowski wrote:If this was a file as opposed specifically to user input, I doubt you would be advocating this style, so at best it works in situations where you know that it's the only way you're going to receive numbers.


No, I'd use this style for a file too. Well, these days I might use a Scanner, but before that, yes. By "user input" I really meant any data not under the programmer's direct control. If that's in a file, fine, it's all input as far as I'm concerned. And I've already put in a caveat that I'm assuming performance is not an issue.

Winston Gutkowski wrote:The advantage of a regex (or indeed Scanner) is that it can be applied to any InputStream, so if you're testing, you can change your mode of input; and if you wrap it in a decent utility method, who cares how complicated the actual code is?


Well, I like regex and Scanner, but I don't see a big advantage here. For testing I'd just write a method that takes a String as input, and I can easily call it with any String input I want. Also, how do you apply a regex to an InputStream? The two ways I can think of are to use a Scanner, or read the InputStream into a String, neither of which sounds like what you're talking about. Maybe I'm overlooking a method here?
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:Well, I like regex and Scanner, but I don't see a big advantage here. For testing I'd just write a method that takes a String as input, and I can easily call it with any String input I want. Also, how do you apply a regex to an InputStream? The two ways I can think of are to use a Scanner, or read the InputStream into a String, neither of which sounds like what you're talking about. Maybe I'm overlooking a method here?


I guess it's back to one of my pet peeves: not providing the developer with sufficient flexibility. You may have seen my rant a while back about methods that return booleans when in fact one that returns an index might make a better building block. Or indeed, provide both. (I lost BTW; at least in terms of votes )

My objection to parseInt() is that it forces developers into the all or nothing paradigm of Exceptions; and perhaps this is where we disagree.
Before Scanner (which actually implements 'hasNext...()' pretty much the way I would expect - ie, by using regexes), parseInt() forced you into a world where any anomaly involved an Exception - and therefore a possibly significant performance hit if, in terms of your program, the error is normal and recoverable.

I notice that quite a few things have been changed in v7 to optionally NOT throw Exceptions, which suggests to me that perhaps other people are coming around to my way of thinking (although I'm certainly not counting my chickens yet ) and numeric parsing would seem like a prime candidate. So, you get an invalid string - substitute a pre-determined "invalid" value; or, if it's an Integer, null - and let the developer decide what to do with it.

Personally, I'd be happy to have a method that can parse any int except Integer.MIN_VALUE, using it as an "INVALID", and throws an exception in the specific case where its handed "-2147483648". However, given the amount of time it takes to parse a String anyway, why not just hand back an Integer (or null)?

Winston
 
Mike Simmons
Master Rancher
Posts: 4796
72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oh, I would certainly support better ways to design parseInt() in the first place - or at least, overloads and other methods to more cleanly accomplish various objectives, without exceptions. My point was just that, given parseInt() as it is now, I don't mind using it by catching exceptions. But I'd favor something like:
 
Mike Simmons
Master Rancher
Posts: 4796
72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Winston Gutkowski wrote:You may have seen my rant a while back about methods that return booleans when in fact one that returns an index might make a better building block. Or indeed, provide both. (I lost BTW; at least in terms of votes )


Sure, I was one of the main people arguing with you. Dennis was there too.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:But I'd favor something like:...


Now you see, I suspect that's where we part company (although I definitely applaud the intent).

I don't like cluttered APIs: Old fart; Alzheimers; too much to remember.

Given that you've already got a parseInt() method, what about:?
It returns an Integer if the String is a valid int value, and null if it isn't. And no Exceptions.
I've also ranted about returning nulls (or rather about not catching them quickly), but this seems to me a perfectly acceptable (and documentable) situation in which to do so because it would be part of the API.

BTW, I hope you don't take our butting heads from time to time personally. I really enjoy our little 'contretemps'; and I've learnt quite a lot from you. Not least, how not to be quite such an old fart.

Winston
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:Sure, I was one of the main people arguing with you. Dennis was there too.


Oh, yes. Always remember when I'm shot down in flames...

Winston
 
Mike Simmons
Master Rancher
Posts: 4796
72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Winston Gutkowski wrote:I don't like cluttered APIs: Old fart; Alzheimers; too much to remember.


Yeah, having many methods in an API doesn't bother me, as long as they are well-designed methods that fit the class, with good clear names and reasonable behavior. And my dislike of returning null is strong enough that if someone wants to do it, I'd rather force them to do it explicitly (with parseInt(s, null)) rather than someone picking up that behavior accidentally and forget to check the return value. My preference for Scala's Option type is coloring my thinking here.

Winston Gutkowski wrote:BTW, I hope you don't take our butting heads from time to time personally. I really enjoy our little 'contretemps'; and I've learnt quite a lot from you. Not least, how not to be quite such an old fart.


Agreed, likewise. Not least, how to be more of an old fart.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:My preference for Scala's Option type is coloring my thinking here...


Maybe not; Scala is a language I'm not familiar with.

Most of my views come through experience (some of it bitter; but by no means all). I have a bit of academe, and I understand its merits; but I wonder sometimes how many profs actually had to make a living writing programs for a corporation. Actually, maybe it's better they didn't.

Winston
 
Mike Simmons
Master Rancher
Posts: 4796
72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, most of mine come from experience as well, almost entirely in Java. I just see people not check for null so often, I like solutions that either decrease the likelihood of that, or make it impossible. Scala's approach is to create a data wrapper representing a nullable type like a container with 0 or 1 element. A reference to something that might-or-might-not be there has a different datatype than a reference to something that is there, and you get a compile-time error if you confuse the two without explicitly converting. The syntax is weird at first, but very useful once you get used to it, in my opinion. Unfortunately every time we have a bridge to aJava component, the Scala stuff still has to deal with null (rather than Scala's Option) so I tend to view the nulls as something that is polluting the Scala code and needs to be cleaned out at first opportunity.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:Scala's approach is to create a data wrapper representing a nullable type like a container with 0 or 1 element...The syntax is weird at first, but very useful...


But I can see this is a language I'm going to have to have a look at. Phwaugh. I do like that. Forget closures; gimme some quick null checking.

And I'm NOT kidding - practicality over academe.

Winston
 
Mike Simmons
Master Rancher
Posts: 4796
72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Cool. However I was just looking over some Scala APIs; I suspect you won't be as thrilled with the plethora of arcanely-named methods available on all the collection-type classes.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:Cool. However I was just looking over some Scala APIs; I suspect you won't be as thrilled with the plethora of arcanely-named methods available on all the collection-type classes.


Arcane (within reason) I can stand; it's the 'plethora' the does my old nut in these days.

Winston
 
Campbell Ritchie
Marshal
Posts: 79151
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Winston Gutkowski wrote: . . . gimme some quick null checking. . . .

Do you mean like the ATTACHED type in Eiffel?
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:And my dislike of returning null is strong enough that if someone wants to do it, I'd rather force them to do it explicitly (with parseInt(s, null)) rather than someone picking up that behavior accidentally and forget to check the return value.


Yup, I can see that. In fact I've written a Bounds class for bounds checking based on exactly that principle, except that you supply the "invalid value" at construction time.

Winston
 
reply
    Bookmark Topic Watch Topic
  • New Topic