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

如何在Java中检查字符串是否只包含数字,java,string,Java,String,在Java for String类中有一个名为matches的方法,如何使用该方法使用正则表达式检查我的字符串是否只有数字。我尝试了以下示例,但结果都返回false String regex = "[0-9]"; String data = "23343453"; System.out.println(data.matches(regex)); 和catch异常,它处理减号 尽管数字的数量有限,但这实际上创建了一个可以使用的数据变量,我想这是最常见的用例。试试看 String regex =

在Java for String类中有一个名为matches的方法,如何使用该方法使用正则表达式检查我的字符串是否只有数字。我尝试了以下示例,但结果都返回false

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

和catch异常,它处理减号

尽管数字的数量有限,但这实际上创建了一个可以使用的数据变量,我想这是最常见的用例。

试试看

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

根据Java正则表达式,
+
表示“一次或多次”,而
\d
表示“一个数字”

注意:“双反斜杠”是获取单个反斜杠的转义序列-因此,java字符串中的
\\d
会给出实际结果:
\d

参考文献:


编辑:由于其他答案有些混乱,我正在编写一个测试用例,并将详细解释更多内容

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

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中,
匹配
方法(在问题中指定)匹配完整的字符串,而不是片段。换句话说,不必使用
^\\d+$
(即使它也是正确的)。请参阅最后一个阴性测试用例

请注意,如果您使用在线“regex checker”,则其行为可能会有所不同。要匹配Java中字符串的片段,可以使用
find
方法,如下所述:

问题2: 这个正则表达式是否也与空字符串“
”匹配* 否。正则表达式
\\d*
将匹配空字符串,但
\\d+
不匹配。星形表示零或多个,而加号表示一个或多个。请参阅第一个否定测试用例

问题3 编译正则表达式模式不是更快吗? 是。一次编译正则表达式模式确实比每次调用
匹配项时更快,因此如果性能影响很重要,那么可以像这样编译和使用
模式:

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

您必须允许一个以上的数字(
+
符号),如:


您还可以从Apache Commons使用另一个尚未发布的解决方案:

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

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

我的建议是简单地检查每个字符是否为数字,使用Java 8 lambda表达式可以有效地完成哪些工作:

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

我们可以使用
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

根据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()
}
请尝试这部分代码:

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

}

\d一个数字:[0-9]你应该读懂正则表达式。它们有两个基本元素:原子和量词。您指定了一个原子,但没有指定量词。如果它是一个包含的位数超过整数所能支持的位数的字符串,会发生什么情况?@BrianAgnew您有一个非常大的数字,改为long。如果字符串包含的数字超过了long所能支持的数字,会发生什么情况?我会继续这样说,只要你用有限的支持数字来推广答案:-),除非你强调这是答案的一个限制(我不认为这是不合理的-应该遵守实用性)。事实上,我确实认为您的建议是一个有用的答案,并且我自己也认为在这种检查中使用异常处理是一个非常糟糕的主意。对于捕获的每个异常,都将创建一个对象,并(重新)创建堆栈跟踪。如果您正在处理大量的数据,您将为一项非常琐碎的任务浪费大量的资源。@user2065083通常建议用户使用标准API来解决您的问题。任何人只要读一次就可以理解(并维护)您的代码。因此,从长远来看,它是有益的。请注意,此方法还匹配Unicode数字。请注意,此方法还将匹配字符串,例如
0xAF
2.3e-4
123L
。注意导入
org.apache.commons.lang.math.NumberUtils
,而不是不推荐使用的
org.apache.commons.lang.NumberUtils
。有一个值得注意的警告。如果您这样做,那么NumberUtil.isNumber(“1000D”)将返回true,因此如果您真的只查找数字,这将不起作用。您是否在解决方案和正则表达式之间进行过任何基准测试?我怀疑它的性能比正则表达式好,但不能肯定@嗯,我刚刚做了一个基准测试:。短字符串的差异可以忽略不计。然而,流对于非常长的字符串来说效果更好(对于1亿个字符的字符串来说速度快2倍)。是的,对于大字符串来说是有意义的。“我应该提到我对这个问题的意思。”MaxMalysh回答得很好
Character.isDigit(x)
可以进一步简化为
Character::isDigit
“0१२३14586“这也将以数字形式传递:)'\u0030'到'\u0039',ISO-LATIN-1数字('0'到'9'),\u0660'到'\u0669',阿拉伯-印度数字'\u06F0'到'\u06F9',扩展阿拉伯-印度数字'\u0966'到'\u096F',Devanagari数字'\uFF10'到'\uFF19',全宽数字此失败对象仅包含数字(“0123456058782”);
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
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()
}
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");
    }

}