We help IT Professionals succeed at work.

Regular expression problem

KNVB HK
KNVB HK asked
on
Medium Priority
605 Views
Last Modified: 2010-03-31
I want to use regular expression to validate a string is a number or not.
Here is my code:

    Pattern p = Pattern.compile("/\\d/");
    Matcher m = p.matcher(strNumber);
    bIsNullString = m.matches();
    System.out.println(strNumber+","+m.matches());

why m.matches() alway return false even the value of strNumber is "1", can you tell me why?

In javascript, I can use /\d*.{0,1}\d*/ pattern to fullfill my need.
Is it possible to implement the same thing in java?
When I execute the command "java -version"(-version parameter is used to print java version) on my pc, I got the following message:

D:\java>java -version
java version "1.4.1_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_02-b06)
Java HotSpot(TM) Client VM (build 1.4.1_02-b06, mixed mode)
Comment
Watch Question

Mayank SPrincipal Technologist
CERTIFIED EXPERT

Commented:
Try "[0-9]+".
Mayank SPrincipal Technologist
CERTIFIED EXPERT

Commented:
I haven't worked much with regex, but I guess in your code, it should be "\\d" ?
Mayank SPrincipal Technologist
CERTIFIED EXPERT

Commented:
>> Try "[0-9]+"

You can also have "[0-9]*" but that would be for 0 or more matches - means that it can give true even when there are none. [0-9]+ would ensure at least one match.
KNVB HKSITO
CERTIFIED EXPERT

Author

Commented:
First, I should thank you for your help.
My program works fine for integer only.
However, I want my program also allow the user input a decimal no.,so would you tell me how to do so?
Mayank SPrincipal Technologist
CERTIFIED EXPERT

Commented:
I guess a non-negative floating-point (or double) can be specified using:

"(\\d){1,10}\\.(\\d){1,10}"
Mayank SPrincipal Technologist
CERTIFIED EXPERT

Commented:
I assumed a size-limit there.
CERTIFIED EXPERT
Top Expert 2016

Commented:
The reason for your difficultly lies in the way you've specified your pattern. In some scripting languages, including Perl and JavaScript, the pattern is contained the forward slashes

/somePattern/

This is not only unnecessary in Java, but will break it. It should be just

somePattern

(in your case "\\d"). Be careful also with the distinction between Matcher.matches and Matcher.find. The former must match ALL the input

Commented:
Taking on board all the comments so far, and adding an additional assumption that you want to match the entire string.
i.e. "23" should match, but "this contains 23" should not:
Use \A to anchor the start of the string, \z to anchor the end.  The regular expression is contained within quotes, with no need for '/' delimiters.

Pattern p = Pattern.compile("\\A\\d+\\z");

If you want "23", "23.2" "0.43" but not ".2" or "20." to match:
Pattern p = Pattern.compile("\\A\\d+(?:\\.\\d+)\\z");

And, if you want to allow a leading + or -:
Pattern p = Pattern.compile("\\A[-+]\\d+(?:\\.\\d+)\\z");

Commented:
There's always a typo...

Non-capturing fractional part "(?:....)" needs to be option by adding a trailing ?
If you want "23", "23.2" "0.43" but not ".2" or "20." to match:
Pattern p = Pattern.compile("\\A\\d+(?:\\.\\d+)?\\z");

And, if you want to allow a leading + or -:
Pattern p = Pattern.compile("\\A[-+]\\d+(?:\\.\\d+)?\\z");
KNVB HKSITO
CERTIFIED EXPERT

Author

Commented:
Hello everybody:
In fact, I am writing "number to text" function.
do you think whether I need to take care the "-" sign?

I found that the pattern [0-9]*\\.{0,1}[0-9]* can fullfill my need, when I don't take care the "-" sign.

CERTIFIED EXPERT
Top Expert 2016

Commented:
You probably do need to take care of it then
Mayank SPrincipal Technologist
CERTIFIED EXPERT

Commented:
Perhaps: "-*[0-9]*\\.{0,1}[0-9]*" ??
Mayank SPrincipal Technologist
CERTIFIED EXPERT

Commented:
Sorry, perhaps: "-??[0-9]*\\.{0,1}[0-9]*"
KNVB HKSITO
CERTIFIED EXPERT

Author

Commented:
how about this one?

-{0,1}[0-9]*\\.{0,1}[0-9]*
Mayank SPrincipal Technologist
CERTIFIED EXPERT

Commented:
Should work.

Commented:
Isn't it standard practice to use ? instead of {0,1}.
I'd have thought people reading regular expressions parse ? mentally as 'optional', where as it takes a bit of thought to realise that {0,1} is doing exactly the same thing...

So:
-{0,1}[0-9]*\\.{0,1}[0-9]*

becomes
-?[0-9]*\\.?[0-9]*

But, that accepts "", "-", "-." and "." (as does the expression with {0,1})


CERTIFIED EXPERT
Top Expert 2016

Commented:
>>Isn't it standard practice to use ? instead of {0,1}.

Yes, and much better of course

Not sure if i get your last sentence searlas...
Mayank SPrincipal Technologist
CERTIFIED EXPERT

Commented:
>> Isn't it standard practice to use ? instead of {0,1}

Yes, it is. That's why I used -?? (zero or one appearance of - ).

If we assume that a 0 or at least any other digit is essential before the decimal-point, then we can have:

"-??[0-9]+\\.??[0-9]*"

Commented:
Why use a reluctant qualifier? (double ??)

I'm just aiming for clarity here and consistency with the bare essentials of regular expressions.  I think a reluctant qualifier is only necessary when it could cause a regular expression to fail e.g.
[0-9]?[0-9]
This would fail to match "0", "1", "2", ....
But,
[0-9]??[0-9] would match "0", "1", "2", ...

However, as you're qualifying a "-" and a "." which have no bearing in whether decimal numbers match, there seems to be no point in using a reluctant qualifier, and it causes the reader/maintainer to double-check Java's regular expression spec to see what the double ?? actually means.

Well, it caused me to read the Pattern javadocs.  Unnecessarily.
CERTIFIED EXPERT
Top Expert 2016

Commented:
LOL me too - always a good read though ;-)
KNVB HKSITO
CERTIFIED EXPERT

Author

Commented:
I want to ensure that at most 1 decimal point in the string.
I want to ensure that at most 1 negative sign"-" in the string.
CERTIFIED EXPERT
Top Expert 2016

Commented:
(implemented ;-))
Principal Technologist
CERTIFIED EXPERT
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION
CERTIFIED EXPERT
Top Expert 2016

Commented:
Wait a minute mayank - haven't those been rejected for the reasons we've been discussing..?
CERTIFIED EXPERT
Top Expert 2016

Commented:
cstang:

a. that particular answer (*at that point in the thread*) should not have been accepted as the answer for the reasons just given
b. both mayank and searlas have been refining this answer (i've just been chipping in) and BOTH of them should have been credited in a points split

I'm not getting at you mayank of course, just trying to see a precise answer coming out of all this work that's gone in
Mayank SPrincipal Technologist
CERTIFIED EXPERT

Commented:
All would work, though. I still don't favour or reject any one of them.
Mayank SPrincipal Technologist
CERTIFIED EXPERT

Commented:
>> should have been credited in a points split

No issues with that.
Mayank SPrincipal Technologist
CERTIFIED EXPERT

Commented:
You can post a question "Points for searlas" and give him points there. Or if you want to go the long way, you can ask CS to reopen this one and then split.

Commented:
cstang,

Do not use  "-{0,1}[0-9]*\\.{0,1}[0-9]*"
(Nor the alternatives with ? or ??)
This expression matches the empty string, "-", "." and "-." on their own.  i.e. no numbers at all.  As stated in this comment.
https://www.experts-exchange.com/Programming/Programming_Languages/Java/Q_20931464.html#10675307

And this: "-??[0-9]+\\.??[0-9]*"
It depends on your requirements, but you should know it'll accept numbers with a trailing decimal point, but not numbers with a leading decimal point.  i.e. it accepts "23." and "-23."  but not ".23" or "-.23"

With respect to points, I'd just be happy if cstang uses the simplest/clearest pattern that meets their requirements.  
Mayank SPrincipal Technologist
CERTIFIED EXPERT

Commented:
>> "-??[0-9]+\\.??[0-9]*"

Oh sorry. I did not notice the * at the end.

Perhaps if you restrict it to something like (+/-) x.y, then you can have: "-??[0-9]+\\.??[0-9]+"
CERTIFIED EXPERT
Top Expert 2016

Commented:
That's still of course ignoring the earlier remarks about greedy quantifiers
Mayank SPrincipal Technologist
CERTIFIED EXPERT

Commented:
Yes.
Mayank SPrincipal Technologist
CERTIFIED EXPERT

Commented:
I haven't worked much with regex, like I pointed right at the start, so as of now, for me - as long as it works, its good ;-) will work with it more.
CERTIFIED EXPERT
Top Expert 2016

Commented:
To summarize (cstang: searlas is happy - you can forget the points split)

Tweaking :


>>Perhaps if you restrict it to something like (+/-) x.y, then you can have: "-?[0-9]+\\.?[0-9]+"

That looks good and simple to me
KNVB HKSITO
CERTIFIED EXPERT

Author

Commented:
I have try the following pattern:

"-??[0-9]+\\.??[0-9]*"

It can filter out single "-" and ".". Also it can also allow user input "1.". Therefore, I select this comment as answer.

CERTIFIED EXPERT
Top Expert 2016

Commented:
I give up now LOL

Commented:
OK.  I'm curious what you meant when you said:
    In fact, I am writing "number to text" function.

You do know your chosen pattern will also allow user input "R2D2" and "C3PO" don't you?

KNVB HKSITO
CERTIFIED EXPERT

Author

Commented:
hey searlas:

I have tested the pattern, it can filter out both "R2D2" and "C3PO"
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.