179

In Java for String class there is a method called matches, how to use this method to check if my string is having 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));
akash
  • 22,664
  • 11
  • 59
  • 87
Chaitanya
  • 15,403
  • 35
  • 96
  • 137

12 Answers12

410

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());
Nicolás Alarcón Rapela
  • 2,714
  • 1
  • 18
  • 29
vikingsteve
  • 38,481
  • 23
  • 112
  • 156
35

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

Ilya Serbis
  • 21,149
  • 6
  • 87
  • 74
Apurv
  • 3,723
  • 3
  • 30
  • 51
  • 1
    @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. – Apurv Feb 27 '13 at 12:28
  • 4
    Note that this method matches also **Unicode digits**. – user11153 Aug 14 '14 at 12:55
  • 3
    Note that this will also match strings such as `0xAF`, `2.3e-4` and `123L`. – vikingsteve Oct 29 '15 at 11:15
  • 4
    Note to import `org.apache.commons.lang.math.NumberUtils` instead of `org.apache.commons.lang.NumberUtils` which is deprecated. – Lucky Mar 12 '16 at 14:39
  • 1
    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. – kasdega Jan 23 '18 at 16:56
  • From Apache Commons, StringUtils.isNumeric(CharSequence cs) gives the expected result https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html#isNumeric-java.lang.CharSequence- – Emmanuel Guiton Jan 26 '22 at 15:32
  • If the string starts with 0, the apache method will return false if any of the following digits is not allowed in an octal number (i.e. digit > 7). Example `NumberUtils.isCreatable("0228")` returns false because of the 8 digit. – francisco neto Dec 29 '22 at 13:10
  • `NumberUtils.isNumber(String)` is deprecated. This feature will be removed in Lang 4.0, use `isCreatable(String)` instead. – francisco neto Dec 29 '22 at 13:22
  • It might better to use `NumberUtils.isDigits` instead. In order to dodge the unicodes from evaluation. – starkm May 04 '23 at 10:40
18

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));
Max Malysh
  • 29,384
  • 19
  • 111
  • 115
  • 1
    Have you done any benchmarking between your solution and regex? I doubt it performs better than regex but can't be sure! – Ean V Feb 06 '16 at 12:57
  • 1
    @Ean well, I've just made a benchmark: https://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). – Max Malysh Feb 06 '16 at 16:38
  • 1
    Yes, makes sense for large strings. Should've mentioned I meant for this question. – Ean V Feb 10 '16 at 04:31
  • 3
    @MaxMalysh great answer! `Character.isDigit(x)` can be further simplified to `Character::isDigit`. – mre May 02 '18 at 19:45
  • "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 – Igor Vuković Oct 20 '20 at 07:59
  • Fails on a decimal point. – ggb667 Nov 01 '21 at 05:54
11

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

String regex = "\\p{Digit}+"; // uses POSIX character class
jlordo
  • 37,490
  • 6
  • 58
  • 83
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));
Carlo Pellegrini
  • 5,656
  • 40
  • 45
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.

NimChimpsky
  • 46,453
  • 60
  • 198
  • 311
  • 4
    What happens if it's a string which contains more digits than Integer can support ? – Brian Agnew Feb 27 '13 at 11:53
  • @BrianAgnew you have a very big number, changed to long. – NimChimpsky Feb 27 '13 at 11:54
  • 3
    What happens if it's a string which contains more digits than Long can support ? – Brian Agnew Feb 27 '13 at 11:57
  • @BrianAgnew I change my answer to big decimal ... and then you say the same again ? (i am not arguing with your point, but I think my answer can still be useful in some cases). Such as you want to actually use the data in your code, not just validate it. – NimChimpsky Feb 27 '13 at 11:57
  • 4
    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 – Brian Agnew Feb 27 '13 at 12:00
  • @BrianAgnew I think your comment has done that for me but I have editted anyway – NimChimpsky Feb 27 '13 at 12:02
  • 1
    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. – ccdan Oct 28 '17 at 19:23
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
Luan Vo
  • 221
  • 3
  • 8
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

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;
        }
    }
npe
  • 34
  • 3
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

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
Santh
  • 2,221
  • 1
  • 5
  • 7
0

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.

Remzi Cavdar
  • 135
  • 1
  • 13
-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");
    }

}
Nomade
  • 1,760
  • 2
  • 18
  • 33
siva
  • 1
  • 2