Java中如何检查一个字符串是否只包含数字

180
在Java中,String类有一个称为matches的方法,如何使用该方法来检查我的字符串是否只包含数字,使用正则表达式。我尝试了以下示例,但它们都返回false作为结果。
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
题目:Java中如何判断一个字符串是否只包含数字,而不包含字母?回答: 可以使用正则表达式来判断一个字符串是否只包含数字。具体实现如下:public static boolean isNumeric(String str) { if (str == null || str.length() == 0) { return false; } return str.matches("^[0-9]+$"); }其中,^$ 分别表示匹配字符串的起始位置和结束位置, [0-9] 表示匹配数字,+ 表示匹配前面的字符一次或多次。如果字符串符合该正则表达式,则返回 true,否则返回 false。注意,该方法仅适用于 ASCII 编码的数字。如果要支持 Unicode 编码的数字,需要使用其他方式实现。 - BobTheBuilder
\d 代表一个数字:[0-9]。 http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html - Christophe Roussy
2
你应该学习正则表达式。它们有两个主要元素:原子和量词。你已经指定了一个原子,但没有指定量词。 - Kyle Strand
12个回答

413

尝试

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

或者

String regex = "\\d+";

根据Java的正则表达式,+表示“出现一次或多次”,\d表示“数字”。
注意:双反斜杠是一个转义序列,用于获取单个反斜杠 - 因此,在Java字符串中,\\d将给出实际结果:\d 参考资料:
- Java正则表达式 - Java字符转义序列

编辑:由于其他答案存在一些混淆,我正在编写一个测试用例,并会详细解释一些事情。

首先,如果您对此解决方案(或其他解决方案)的正确性有疑问,请运行此测试用例:

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));

问题1:

在正则表达式中加入^$是不是必要的,这样它就不会匹配到"aa123bb"了?

不需要。 在Java中,matches方法(在问题中指定)匹配整个字符串,而不是片段。换句话说,使用^\\d+$并不是必要的(即使它也是正确的)。请参见最后一个负测试用例。

请注意,如果您使用在线“正则表达式检查器”,则可能会有所不同。要在Java中匹配字符串的片段,可以使用find方法,详细描述如下:

Java Regex中matches()和find()之间的区别

问题2:

这个正则表达式是否也会匹配空字符串""?*

第三题

\\d*的正则表达式可以匹配空字符串,但\\d+不能。星号*表示零个或多个,而加号+表示一个或多个。请参见第一个负测试用例。

编译正则表达式模式不是更快吗?

是的。 编译正则表达式模式一次比在每次调用matches时编译要快,因此如果性能影响重要,则可以编译并像这样使用Pattern

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());

35

1
@user2065083 建议您使用标准API来解决问题。任何人只需阅读一次即可理解(和维护)您的代码。因此,从长期来看,这是有益的。 - Apurv
4
请注意,这种方法也匹配Unicode数字 - user11153
3
请注意,这也将匹配字符串,如0xAF2.3e-4123L - vikingsteve
4
请注意导入org.apache.commons.lang.math.NumberUtils而不是已经被弃用的org.apache.commons.lang.NumberUtils - Lucky
1
这里有一个需要提醒的注意事项。如果你这样做,要知道 NumberUtil.isNumber("1000D") 会返回 true,所以如果你真的只想要数字,那么这个方法就不适用了。 - kasdega
显示剩余4条评论

18

使用正则表达式在性能方面代价高昂。尝试将字符串解析为长整型值是低效且不可靠的,可能并不是您所需要的。

我建议的方法是简单地检查每个字符是否为数字,这可以使用Java 8的lambda表达式高效实现:

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

1
你是否对你的解决方案和正则表达式进行过基准测试?我怀疑它的性能不如正则表达式,但不能确定! - Ean V
1
@Ean 嗯,我刚刚做了一个基准测试:https://gist.github.com/maxmalysh/a991bbe4a923539f19fb。对于短字符串来说,差别微不足道。然而,对于真正长的字符串,流的效果更好(对于一亿个字符的字符串,速度快了2倍)。 - Max Malysh
1
是的,对于大字符串来说是有意义的。我应该在这个问题中提到这一点。 - Ean V
3
@MaxMalysh的回答很好!Character.isDigit(x)可以进一步简化为Character::isDigit - mre
"0१२३14586" 这也可以被视为数字 :) '\u0030' 到 '\u0039',ISO-LATIN-1 数字('0' 到 '9') '\u0660' 到 '\u0669',阿拉伯-印度数字 '\u06F0' 到 '\u06F9',扩展阿拉伯-印度数字 '\u0966' 到 '\u096F',天城文数字 '\uFF10' 到 '\uFF19',全角数字 - Igor Vuković
小数点出错。 - ggb667

12

还有一种解决办法,尚未发布:

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

9

您需要允许多于一个数字(加号+)的情况,例如:

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

7
Long.parseLong(data)

并且捕获异常,处理减号。虽然所能容纳的数字位数有限,但这实际上创建了一个可用的数据变量,我想这是最常见的用法。


4
如果一个字符串包含的数字超过了整型所能支持的范围,会发生什么? - Brian Agnew
@BrianAgnew 你有一个非常大的数字,请改为 long。 - NimChimpsky
3
如果一个字符串中包含的数字超过了 Long 类型所能支持的范围,会发生什么? - Brian Agnew
4
只要你推荐的答案有限定的位数,我就会一直这么说 :-) 除非你将这个限制作为答案的一部分(我认为这并不不合理 - 实际情况应该得到考虑)。实际上,我确实认为你提出的建议是一个有用的答案,而我自己也考虑过它。 - Brian Agnew
1
使用异常处理来进行这种检查真的是一个非常糟糕的想法。每次捕获异常时,都会创建一个对象并重新创建一个堆栈跟踪。如果您正在处理大量数据,则会为一个相当琐碎的任务浪费大量资源。 - ccdan
显示剩余2条评论

2
根据Oracle的Java文档:
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()
}

OC 要求一个正则表达式,用于匹配仅由数字组成的字符串,而不是所有可能的数字。 - DDay

2
我们可以使用Pattern.compile("[0-9]+.[0-9]+")Pattern.compile("\\d+.\\d+")。它们具有相同的含义。
模式[0-9]表示数字,与'\d'相同。 '+'表示它出现的次数更多。 '.'表示整数或浮点数。
尝试以下代码:
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");
        }

    }

输出:

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

1
这个失败了: obj.containNumbersOnly("0123456,058782"); - Phoenix404

1

请参考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;
        }
    }

0
在 Java 中的 String 类中,有一个叫做 matches() 的方法。通过使用这个方法,你可以验证正则表达式是否与你的字符串匹配。
String regex = "^[\\d]{4}$";
   
String value = "1234";

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

上面正则表达式的解释是:

  • ^ - 表示正则表达式的开始。

  • [] - 在此内部,您必须描述自己的条件。

  • \\\d - 仅允许数字。您可以在括号内使用'\\d'或0-9,它们都是相同的。

  • {4} - 此条件允许恰好4个数字。您可以根据需要更改数字。

  • $ - 表示正则表达式的结尾。

注意: 您可以删除 {4} 并指定 +,表示一次或多次,或 * 表示零次或多次,或 ? 表示一次或没有。

有关更多参考,请查看此网站:https://www.rexegg.com/regex-quickstart.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接