182

In Java for String class there is a method called matches. How to use this method to check if my string has only digits using regular expression? I tried with below examples, but both of them returned me false as result:

String regex = "[0-9]";
String data = "23343453";
System.out.println(data.matches(regex));
String regex = "^[0-9]";
String data = "23343453";
System.out.println(data.matches(regex));
3

13 Answers 13

420

Try

String regex = "[0-9]+";

or

String regex = "\\d+";

As per Java regular expressions, the + means "one or more times" and \d means "a digit".

Note: the "double backslash" is an escape sequence to get a single backslash - therefore, \\d in a java String gives you the actual result: \d

References:


Edit: due to some confusion in other answers, I am writing a test case and will explain some more things in detail.

Firstly, if you are in doubt about the correctness of this solution (or others), please run this test case:

String regex = "\\d+";

// positive test cases, should all be "true"
System.out.println("1".matches(regex));
System.out.println("12345".matches(regex));
System.out.println("123456789".matches(regex));

// negative test cases, should all be "false"
System.out.println("".matches(regex));
System.out.println("foo".matches(regex));
System.out.println("aa123bb".matches(regex));

Question 1:

Isn't it necessary to add ^ and $ to the regex, so it won't match "aa123bb" ?

No. In java, the matches method (which was specified in the question) matches a complete string, not fragments. In other words, it is not necessary to use ^\\d+$ (even though it is also correct). Please see the last negative test case.

Please note that if you use an online "regex checker" then this may behave differently. To match fragments of a string in Java, you can use the find method instead, described in detail here:

Difference between matches() and find() in Java Regex

Question 2:

Won't this regex also match the empty string, "" ?*

No. A regex \\d* would match the empty string, but \\d+ does not. The star * means zero or more, whereas the plus + means one or more. Please see the first negative test case.

Question 3

Isn't it faster to compile a regex Pattern?

Yes. It is indeed faster to compile a regex Pattern once, rather than on every invocation of matches, and so if performance implications are important then a Pattern can be compiled and used like this:

Pattern pattern = Pattern.compile(regex);
System.out.println(pattern.matcher("1").matches());
System.out.println(pattern.matcher("12345").matches());
System.out.println(pattern.matcher("123456789").matches());
Sign up to request clarification or add additional context in comments.

Comments

35

You can also use NumberUtil.isNumber(String str) from Apache Commons

9 Comments

@user2065083 Its always recommended to user standard API to solve your problem. Anyone giving it a single read can understand (and maintain) your code. So its beneficial from long term point of view.
Note that this method matches also Unicode digits.
Note that this will also match strings such as 0xAF, 2.3e-4 and 123L.
Note to import org.apache.commons.lang.math.NumberUtils instead of org.apache.commons.lang.NumberUtils which is deprecated.
There is a caveat to this that bears mentioning. If you do this know that NumberUtil.isNumber("1000D") will return true, so if you're really looking for only digits this this will not work.
|
17

Using regular expressions is costly in terms of performance. Trying to parse string as a long value is inefficient and unreliable, and may be not what you need.

What I suggest is to simply check if each character is a digit, what can be efficiently done using Java 8 lambda expressions:

boolean isNumeric = someString.chars().allMatch(x -> Character.isDigit(x));

6 Comments

Have you done any benchmarking between your solution and regex? I doubt it performs better than regex but can't be sure!
@Ean well, I've just made a benchmark: gist.github.com/maxmalysh/a991bbe4a923539f19fb. The difference for short strings is negligible. However, streams work better for really long strings (2x times faster for 100-million character string).
Yes, makes sense for large strings. Should've mentioned I meant for this question.
@MaxMalysh great answer! Character.isDigit(x) can be further simplified to Character::isDigit.
"0१२३14586" this will also pass as numeric :) '\u0030' through '\u0039', ISO-LATIN-1 digits ('0' through '9') '\u0660' through '\u0669', Arabic-Indic digits '\u06F0' through '\u06F9', Extended Arabic-Indic digits '\u0966' through '\u096F', Devanagari digits '\uFF10' through '\uFF19', Fullwidth digits
|
12

One more solution, that hasn't been posted, yet:

String regex = "\\p{Digit}+"; // uses POSIX character class

Comments

9

You must allow for more than a digit (the + sign) as in:

String regex = "[0-9]+"; 
String data = "23343453"; 
System.out.println(data.matches(regex));

Comments

7
Long.parseLong(data)

and catch exception, it handles minus sign.

Although the number of digits is limited this actually creates a variable of the data which can be used, which is, I would imagine, the most common use-case.

7 Comments

What happens if it's a string which contains more digits than Integer can support ?
@BrianAgnew you have a very big number, changed to long.
What happens if it's a string which contains more digits than Long can support ?
I'll keep on saying it so long as you promote an answer with a limited number of supported digits :-) Unless you highlight that as a limitation of the answer (which I don't think is unreasonable - practicalities should be observed). I do in fact think what you're proposing is a useful answer, and had considered it myself
It's a really bad idea to use exception handling for this kind of check. For every exception that is caught, an object will be created and a stack trace will also be (re)created. If you're processing a non-trivial amount of data, you'll waste a ridiculous amount of resources for a rather trivial task.
|
2

We can use either Pattern.compile("[0-9]+.[0-9]+") or Pattern.compile("\\d+.\\d+"). They have the same meaning.

the pattern [0-9] means digit. The same as '\d'. '+' means it appears more times. '.' for integer or float.

Try following code:

import java.util.regex.Pattern;

    public class PatternSample {

        public boolean containNumbersOnly(String source){
            boolean result = false;
            Pattern pattern = Pattern.compile("[0-9]+.[0-9]+"); //correct pattern for both float and integer.
            pattern = Pattern.compile("\\d+.\\d+"); //correct pattern for both float and integer.

            result = pattern.matcher(source).matches();
            if(result){
                System.out.println("\"" + source + "\""  + " is a number");
            }else
                System.out.println("\"" + source + "\""  + " is a String");
            return result;
        }

        public static void main(String[] args){
            PatternSample obj = new PatternSample();
            obj.containNumbersOnly("123456.a");
            obj.containNumbersOnly("123456 ");
            obj.containNumbersOnly("123456");
            obj.containNumbersOnly("0123456.0");
            obj.containNumbersOnly("0123456a.0");
        }

    }

Output:

"123456.a" is a String
"123456 " is a String
"123456" is a number
"0123456.0" is a number
"0123456a.0" is a String

1 Comment

this fails obj.containNumbersOnly("0123456,058782");
2

According to Oracle's Java Documentation:

private static final Pattern NUMBER_PATTERN = Pattern.compile(
        "[\\x00-\\x20]*[+-]?(NaN|Infinity|((((\\p{Digit}+)(\\.)?((\\p{Digit}+)?)" +
        "([eE][+-]?(\\p{Digit}+))?)|(\\.((\\p{Digit}+))([eE][+-]?(\\p{Digit}+))?)|" +
        "(((0[xX](\\p{XDigit}+)(\\.)?)|(0[xX](\\p{XDigit}+)?(\\.)(\\p{XDigit}+)))" +
        "[pP][+-]?(\\p{Digit}+)))[fFdD]?))[\\x00-\\x20]*");
boolean isNumber(String s){
return NUMBER_PATTERN.matcher(s).matches()
}

1 Comment

OC asked for a regex to match a string of only digits, not all possible numbers.
1

Refer to org.apache.commons.lang3.StringUtils

    public static boolean isNumeric(CharSequence cs) {
        if (cs == null || cs.length() == 0) {
            return false;
        } else {
            int sz = cs.length();

            for(int i = 0; i < sz; ++i) {
                if (!Character.isDigit(cs.charAt(i))) {
                    return false;
                }
            }

            return true;
        }
    }

Comments

0

In Java for String class, there is a method called matches(). With help of this method you can validate the regex expression along with your string.

String regex = "^[\\d]{4}$";
   
String value = "1234";

System.out.println(data.matches(value));

The Explanation for the above regex expression is:-

  • ^ - Indicates the start of the regex expression.

  • [] - Inside this you have to describe your own conditions.

  • \\\d - Only allows digits. You can use '\\d'or 0-9 inside the bracket both are same.

  • {4} - This condition allows exactly 4 digits. You can change the number according to your need.

  • $ - Indicates the end of the regex expression.

Note: You can remove the {4} and specify + which means one or more times, or * which means zero or more times, or ? which means once or none.

For more reference please go through this website: https://www.rexegg.com/regex-quickstart.html

Comments

0

To account for other digits beside Latin/English (aka Western Arabic digits):

var regex = "\\p{javaDigit}+"; // Same as "\\p{Nd}+"
"1234۱۲۳۴".matches(regex); // true

For Kotlin:

"1234۱۲۳۴".all(Char::isDigit) // true
// OR
"1234۱۲۳۴" matches Regex("\\p{javaDigit}") // Same as "\\p{Nd}"

Comments

-1

Try this part of code:

void containsOnlyNumbers(String str)
{
    try {
        Integer num = Integer.valueOf(str);
        System.out.println("is a number");
    } catch (NumberFormatException e) {
        // TODO: handle exception
        System.out.println("is not a number");
    }

}

Comments

-1

Offical regex way

I would use this regex for integers:

^[-1-9]\d*$

This will also work in other programming languages because it's more specific and doesn't make any assumptions about how different programming languages may interpret or handle regex.

Also works in Java

\\d+

Questions regarding ^ and $

As @vikingsteve has pointed out in java, the matches method matches a complete string, not parts of a string. In other words, it is unnecessary to use ^\d+$ (even though it is the official way of regex).

Online regex checkers are more strict and therefore they will behave differently than how Java handles regex.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.