如何在Java中检查一个字符串是否是数字

1047

在解析字符串之前,如何检查它是否为数字?


42
所有使用正则表达式提出的解决方案都不能用于十六进制数字。 - Oscar Castiblanco
在编程中,传递空字符串到matches(...)函数将会抛出NullPointer异常。 - Hitesh Sahu
请参考Max Malysh的答案,其中提供了一个简洁的Java 8解决方案,无需使用第三方库。 - Andy Thomas
@HiteshSahu 最新版本(包括Java 6.x和7.x)似乎能够优雅地处理null字符串。 - lifebalance
所有提出使用Integer.parseInt()的解决方案都无法正确解析包含“NumberFormatException”的移动电话号码。 - Not a bug
@OscarCastiblanco 在给定的基数中,_所有_字符串都是数字。 - bfontaine
41个回答

4
您可以使用java.util.Scanner对象。
public static boolean isNumeric(String inputData) {
      Scanner sc = new Scanner(inputData);
      return sc.hasNextInt();
    }

3
// only int
public static boolean isNumber(int num) 
{
    return (num >= 48 && c <= 57); // 0 - 9
}

// is type of number including . - e E 
public static boolean isNumber(String s) 
{
    boolean isNumber = true;
    for(int i = 0; i < s.length() && isNumber; i++) 
    {
        char c = s.charAt(i);
        isNumber = isNumber & (
            (c >= '0' && c <= '9') || (c == '.') || (c == 'e') || (c == 'E') || (c == '')
        );
    }
    return isInteger;
}

// is type of number 
public static boolean isInteger(String s) 
{
    boolean isInteger = true;
    for(int i = 0; i < s.length() && isInteger; i++) 
    {
        char c = s.charAt(i);
        isInteger = isInteger & ((c >= '0' && c <= '9'));
    }
    return isInteger;
}

public static boolean isNumeric(String s) 
{
    try
    {
        Double.parseDouble(s);
        return true;
    }
    catch (Exception e) 
    {
        return false;
    }
}

3
这是一个关于此检查的简单示例:
public static boolean isNumericString(String input) {
    boolean result = false;

    if(input != null && input.length() > 0) {
        char[] charArray = input.toCharArray();

        for(char c : charArray) {
            if(c >= '0' && c <= '9') {
                // it is a digit
                result = true;
            } else {
                result = false;
                break;
            }
        }
    }

    return result;
}

3

根据其他答案,我写了自己的代码,它不使用模式或解析和异常检查。

它检查最大一个减号并检查最多一个小数点。

这里有一些示例及其结果:

"1","-1","-1.5"和"-1.556"返回true

"1..5","1A.5","1.5D","-"和"--1"返回false

注意:如有需要,您可以修改此代码以接受区域设置参数,并将其传递给DecimalFormatSymbols.getInstance()调用,以使用特定区域设置而不是当前区域设置。

 public static boolean isNumeric(final String input) {
    //Check for null or blank string
    if(input == null || input.isBlank()) return false;

    //Retrieve the minus sign and decimal separator characters from the current Locale
    final var localeMinusSign = DecimalFormatSymbols.getInstance().getMinusSign();
    final var localeDecimalSeparator = DecimalFormatSymbols.getInstance().getDecimalSeparator();

    //Check if first character is a minus sign
    final var isNegative = input.charAt(0) == localeMinusSign;
    //Check if string is not just a minus sign
    if (isNegative && input.length() == 1) return false;

    var isDecimalSeparatorFound = false;

    //If the string has a minus sign ignore the first character
    final var startCharIndex = isNegative ? 1 : 0;

    //Check if each character is a number or a decimal separator
    //and make sure string only has a maximum of one decimal separator
    for (var i = startCharIndex; i < input.length(); i++) {
        if(!Character.isDigit(input.charAt(i))) {
            if(input.charAt(i) == localeDecimalSeparator && !isDecimalSeparatorFound) {
                isDecimalSeparatorFound = true;
            } else return false;
        }
    }
    return true;
}

3

对于非负数,请使用以下方式

public boolean isNonNegativeNumber(String str) {
  return str.matches("\\d+");
}

对于任何数字,请使用此代码

public boolean isNumber(String str) {
  return str.matches("-?\\d+");
}

2

这就是为什么我喜欢.NET中的Try*方法。除了传统的类似于Java的Parse方法外,您还有一个TryParse方法。我不擅长Java语法(out参数?),因此请将以下内容视为某种伪代码。但它应该能够清楚地表达这个概念。

boolean parseInteger(String s, out int number)
{
    try {
        number = Integer.parseInt(myString);
        return true;
    } catch(NumberFormatException e) {
        return false;
    }
}

使用方法:

int num;
if (parseInteger("23", out num)) {
    // Do something with num.
}

是的,在Java中没有“输出参数”,并且由于Integer包装器是不可变的(因此不能用作有效引用来存储输出),明智的惯用选项是返回一个可以为null的Integer对象,如果解析失败。一个更丑陋的选择可能是将int [1]作为输出参数传递。 - fortran
是的,我记得有关于为什么Java没有输出参数的讨论。但是,返回一个整数(如果需要,则为null)也可以,尽管我不知道Java在装箱/拆箱方面的性能如何。 - OregonGhost
4
我很喜欢C#,但在Java问题中添加一个.NET的C#代码片段是没有用的,因为这些功能在Java中不存在。 - Shane
如果您不记录异常,这将会创建一个Sonar问题。 - jmhostalet

2

Java 8 流(Stream)、Lambda表达式和函数式接口

处理所有情况(包括字符串为null,字符串为空等

String someString = null; // something="", something="123abc", something="123123"

boolean isNumeric = Stream.of(someString)
            .filter(s -> s != null && !s.isEmpty())
            .filter(Pattern.compile("\\D").asPredicate().negate())
            .mapToLong(Long::valueOf)
            .boxed()
            .findAny()
            .isPresent();

2

我修改了CraigTP的解决方案,使其能够接受科学计数法和点号、逗号作为小数分隔符。

^-?\d+([,\.]\d+)?([eE]-?\d+)?$

例子

var re = new RegExp("^-?\d+([,\.]\d+)?([eE]-?\d+)?$");
re.test("-6546"); // true
re.test("-6546355e-4456"); // true
re.test("-6546.355e-4456"); // true, though debatable
re.test("-6546.35.5e-4456"); // false
re.test("-6546.35.5e-4456.6"); // false

2
将其解析(即使用{{link1:Integer#parseInt}}),然后简单地捕获异常。 =)
澄清一下:parseInt函数检查是否可以以任何情况解析数字(显然),如果您仍要解析它,实际执行解析不会造成任何性能损失。
当然,如果您不想解析它(或者非常非常少地解析它),您可能希望采取不同的方法。

2
如果过度使用,成本很高。 - Daniel Nuriyev
如果您不记录异常,它将创建一个声纳问题。 - jmhostalet
Double.parseDouble - Alex78191

2
您可以使用Apache Commons Lang中的NumberUtils.isCreatable()方法。
由于NumberUtils.isNumber将在4.0版本中弃用,因此请改用NumberUtils.isCreatable()方法。

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