如何检查String中的String是否为数字

时间:2009-07-09 09:49:47

标签: java string numeric

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

39 个答案:

答案 0 :(得分:848)

这通常使用简单的用户定义函数(即Roll-your-own“isNumeric”函数)完成。

类似的东西:

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

但是,如果你正在调用这个函数很多,并且你期望许多检查由于不是一个数字而失败,那么这个机制的性能将不会很好,因为你依赖于被抛出的异常每次失败,这是一项相当昂贵的操作。

另一种方法可能是使用正则表达式来检查数字的有效性:

public static boolean isNumeric(String str) {
  return str.matches("-?\\d+(\\.\\d+)?");  //match a number with optional '-' and decimal.
}

请注意上述RegEx机制,因为如果您使用的是非阿拉伯数字(即0到9之外的数字),它将会失败。这是因为RegEx的“\ d”部分只匹配[0-9],并且实际上并不具有国际数字意义。 (感谢OregonGhost指出这一点!)

或者甚至另一种选择是使用Java的内置java.text.NumberFormat对象来查看解析字符串后解析器位置是否在字符串的末尾。如果是,我们可以假设整个字符串是数字:

public static boolean isNumeric(String str) {
  NumberFormat formatter = NumberFormat.getInstance();
  ParsePosition pos = new ParsePosition(0);
  formatter.parse(str, pos);
  return str.length() == pos.getIndex();
}

答案 1 :(得分:629)

使用Apache Commons Lang 3.5及更高版本:NumberUtils.isCreatableStringUtils.isNumeric

使用Apache Commons Lang 3.4及以下版本:NumberUtils.isNumberStringUtils.isNumeric

您还可以使用StringUtils.isNumericSpace为空字符串返回true并忽略字符串中的内部空格。另一种方法是使用StringUtils.isParsable,它基本上根据Java检查数字是否可解析。 (链接的javadoc包含每种方法的详细示例。)

答案 2 :(得分:140)

如果你在Android上,那么你应该使用:

android.text.TextUtils.isDigitsOnly(CharSequence str)

documentation can be found here

保持简单 。大多数人都可以“重新编程”(同样的事情)。

答案 3 :(得分:116)

正如@CraigTP在他的优秀答案中所提到的,我对使用Exceptions来测试字符串是否为数字也有类似的性能问题。所以我最终分割字符串并使用java.lang.Character.isDigit()

public static boolean isNumeric(String str)
{
    for (char c : str.toCharArray())
    {
        if (!Character.isDigit(c)) return false;
    }
    return true;
}

根据the JavadocCharacter.isDigit(char)会正确识别非拉丁数字。在性能方面,我认为简单的N次比较,其中N是字符串中的字符数,与进行正则表达式匹配相比,计算效率更高。

更新:正如Jean-FrançoisCorbett在评论中指出的那样,上面的代码只会验证正整数,它涵盖了我的大多数用例。下面是更新的代码,它根据系统中使用的默认语言环境正确验证十进制数,并假设小数分隔符仅在字符串中出现一次。

public static boolean isStringNumeric( String str )
{
    DecimalFormatSymbols currentLocaleSymbols = DecimalFormatSymbols.getInstance();
    char localeMinusSign = currentLocaleSymbols.getMinusSign();

    if ( !Character.isDigit( str.charAt( 0 ) ) && str.charAt( 0 ) != localeMinusSign ) return false;

    boolean isDecimalSeparatorFound = false;
    char localeDecimalSeparator = currentLocaleSymbols.getDecimalSeparator();

    for ( char c : str.substring( 1 ).toCharArray() )
    {
        if ( !Character.isDigit( c ) )
        {
            if ( c == localeDecimalSeparator && !isDecimalSeparatorFound )
            {
                isDecimalSeparatorFound = true;
                continue;
            }
            return false;
        }
    }
    return true;
}

答案 4 :(得分:89)

Java 8 lambda表达式。

String someString = "123123";
boolean isNumeric = someString.chars().allMatch( Character::isDigit );

答案 5 :(得分:42)

Google的Guava库提供了一个很好的辅助方法来执行此操作:Ints.tryParse。您可以像Integer.parseInt一样使用它,但如果字符串不解析为有效整数,则返回null而不是抛出异常。请注意,它返回Integer,而不是int,因此您必须将其转换/自动放回到int。

示例:

String s1 = "22";
String s2 = "22.2";
Integer oInt1 = Ints.tryParse(s1);
Integer oInt2 = Ints.tryParse(s2);

int i1 = -1;
if (oInt1 != null) {
    i1 = oInt1.intValue();
}
int i2 = -1;
if (oInt2 != null) {
    i2 = oInt2.intValue();
}

System.out.println(i1);  // prints 22
System.out.println(i2);  // prints -1

然而,截至目前的发布 - 番石榴r11 - 它仍然标记为@Beta。

我没有对它进行基准测试。查看源代码有很多理智检查的开销,但最后他们使用Character.digit(string.charAt(idx)),与上面@Ibrahim的答案相似,但略有不同。在实现过程中没有任何异常处理开销。

答案 6 :(得分:27)

请勿使用例外来验证您的值。 使用Util libs代替apache NumberUtils:

NumberUtils.isNumber(myStringValue);

修改

请注意,如果您的字符串以0开头,则NumberUtils会将您的值解释为十六进制。

NumberUtils.isNumber("07") //true
NumberUtils.isNumber("08") //false

答案 7 :(得分:20)

为什么每个人都在推动异常/正则表达式解决方案?

虽然我可以理解大多数人使用try / catch都没问题,但如果你想经常这样做......那可能会非常费力。

我在这里做的是采用正则表达式,parseNumber()方法和数组搜索方法来查看效率最高的方法。这一次,我只看了整数。

public static boolean isNumericRegex(String str) {
    if (str == null)
        return false;
    return str.matches("-?\\d+");
}

public static boolean isNumericArray(String str) {
    if (str == null)
        return false;
    char[] data = str.toCharArray();
    if (data.length <= 0)
        return false;
    int index = 0;
    if (data[0] == '-' && data.length > 1)
        index = 1;
    for (; index < data.length; index++) {
        if (data[index] < '0' || data[index] > '9') // Character.isDigit() can go here too.
            return false;
    }
    return true;
}

public static boolean isNumericException(String str) {
    if (str == null)
        return false;
    try {  
        /* int i = */ Integer.parseInt(str);
    } catch (NumberFormatException nfe) {  
        return false;  
    }
    return true;
}

我得到的速度结果是:

Done with: for (int i = 0; i < 10000000; i++)...

With only valid numbers ("59815833" and "-59815833"):
    Array numeric took 395.808192 ms [39.5808192 ns each]
    Regex took 2609.262595 ms [260.9262595 ns each]
    Exception numeric took 428.050207 ms [42.8050207 ns each]
    // Negative sign
    Array numeric took 355.788273 ms [35.5788273 ns each]
    Regex took 2746.278466 ms [274.6278466 ns each]
    Exception numeric took 518.989902 ms [51.8989902 ns each]
    // Single value ("1")
    Array numeric took 317.861267 ms [31.7861267 ns each]
    Regex took 2505.313201 ms [250.5313201 ns each]
    Exception numeric took 239.956955 ms [23.9956955 ns each]
    // With Character.isDigit()
    Array numeric took 400.734616 ms [40.0734616 ns each]
    Regex took 2663.052417 ms [266.3052417 ns each]
    Exception numeric took 401.235906 ms [40.1235906 ns each]

With invalid characters ("5981a5833" and "a"):
    Array numeric took 343.205793 ms [34.3205793 ns each]
    Regex took 2608.739933 ms [260.8739933 ns each]
    Exception numeric took 7317.201775 ms [731.7201775 ns each]
    // With a single character ("a")
    Array numeric took 291.695519 ms [29.1695519 ns each]
    Regex took 2287.25378 ms [228.725378 ns each]
    Exception numeric took 7095.969481 ms [709.5969481 ns each]

With null:
    Array numeric took 214.663834 ms [21.4663834 ns each]
    Regex took 201.395992 ms [20.1395992 ns each]
    Exception numeric took 233.049327 ms [23.3049327 ns each]
    Exception numeric took 6603.669427 ms [660.3669427 ns each] if there is no if/null check

免责声明:我并未声称这些方法是100%优化的,它们仅用于演示数据

当且仅当数字是4个字符或更少时,并且每个字符串总是一个数字时,例外获胜...在这种情况下,为什么要检查?

简而言之,如果你经常使用try / catch遇到无效数字会非常痛苦,这是有道理的。我一直遵循的一条重要规则是永远不要使用try / catch进行程序流程。这是一个例子。

有趣的是,简单的if char&lt; 0 || &gt; 9编写非常简单,易于记忆(并且应该以多种语言工作)并且几乎可以赢得所有测试场景。

唯一的缺点是我猜测Integer.parseInt()可能会处理非ASCII数字,而数组搜索方法却没有。


对于那些想知道为什么我说很容易记住字符数组的人,如果你知道没有负面的迹象,你可以很容易地得到一些浓缩的东西:

public static boolean isNumericArray(String str) {
    if (str == null)
        return false;
    for (char c : str.toCharArray())
        if (c < '0' || c > '9')
            return false;
    return true;

最后作为最后一点,我对所接受的例子中的分配运营商感到好奇,所有的选票都是。添加

的分配
double d = Double.parseDouble(...)

不仅没用,因为你甚至不使用该值,但它浪费了处理时间并将运行时间增加了几纳秒(这导致测试增加了100-200毫秒)。我不明白为什么有人会这样做,因为它实际上是降低性能的额外工作。

你认为这会被优化出来......虽然我可能应该检查字节码并看看编译器在做什么。这并没有解释为什么它总是显得更长,但如果它以某种方式被优化了...因此我想知道发生了什么。作为一个注释:更长一点,我的意思是运行测试10000000次迭代,并且多次运行该程序(10x +)总是显示它更慢。

编辑:更新了Character.isDigit()

的测试

答案 8 :(得分:18)

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

CraigTP的正则表达式(如上所示)会产生一些误报。例如。 “23y4”将被视为一个数字,因为'。'匹配任何不是小数点的字符。

此外,它会拒绝任何带有前导'+'

的数字

避免这两个小问题的替代方案是

public static boolean isNumeric(String str)
{
    return str.matches("[+-]?\\d*(\\.\\d+)?");
}

答案 9 :(得分:12)

您可以使用NumberFormat#parse

try
{
     NumberFormat.getInstance().parse(value);
}
catch(ParseException e)
{
    // Not a number.
}

答案 10 :(得分:11)

我们可以尝试将给定字符串中的所有数字替换为(“”),即空格,如果之后字符串的长度为零,则可以说给定字符串仅包含数字。 [如果您认为此答案有帮助,请考虑对其进行投票] 示例:

boolean isNumber(String str){
        if(str.length() == 0)
            return false; //To check if string is empty

        if(str.charAt(0) == '-')
            str = str.replaceFirst("-","");// for handling -ve numbers

        System.out.println(str);

        str = str.replaceFirst("\\.",""); //to check if it contains more than one decimal points

        if(str.length() == 0)
            return false; // to check if it is empty string after removing -ve sign and decimal point
        System.out.println(str);

        return str.replaceAll("[0-9]","").length() == 0;
    }

答案 11 :(得分:11)

如果您使用java开发Android应用,则可以使用TextUtils.isDigitsOnly函数。

答案 12 :(得分:8)

以下是我对这个问题的回答。

一个catch all方法,可用于解析任何类型的解析器的任何String:isParsable(Object parser, String str)。解析器可以是Classobject。这也将允许您使用您编写的自定义解析器,并且应该适用于任何场景,例如:

isParsable(Integer.class, "11");
isParsable(Double.class, "11.11");
Object dateFormater = new java.text.SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");
isParsable(dateFormater, "2001.07.04 AD at 12:08:56 PDT");

这是我的代码完整的方法说明。

import java.lang.reflect.*;

/**
 * METHOD: isParsable<p><p>
 * 
 * This method will look through the methods of the specified <code>from</code> parameter
 * looking for a public method name starting with "parse" which has only one String
 * parameter.<p>
 * 
 * The <code>parser</code> parameter can be a class or an instantiated object, eg:
 * <code>Integer.class</code> or <code>new Integer(1)</code>. If you use a
 * <code>Class</code> type then only static methods are considered.<p>
 * 
 * When looping through potential methods, it first looks at the <code>Class</code> associated
 * with the <code>parser</code> parameter, then looks through the methods of the parent's class
 * followed by subsequent ancestors, using the first method that matches the criteria specified
 * above.<p>
 * 
 * This method will hide any normal parse exceptions, but throws any exceptions due to
 * programmatic errors, eg: NullPointerExceptions, etc. If you specify a <code>parser</code>
 * parameter which has no matching parse methods, a NoSuchMethodException will be thrown
 * embedded within a RuntimeException.<p><p>
 * 
 * Example:<br>
 * <code>isParsable(Boolean.class, "true");<br>
 * isParsable(Integer.class, "11");<br>
 * isParsable(Double.class, "11.11");<br>
 * Object dateFormater = new java.text.SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");<br>
 * isParsable(dateFormater, "2001.07.04 AD at 12:08:56 PDT");<br></code>
 * <p>
 * 
 * @param parser    The Class type or instantiated Object to find a parse method in.
 * @param str   The String you want to parse
 * 
 * @return true if a parse method was found and completed without exception
 * @throws java.lang.NoSuchMethodException If no such method is accessible 
 */
public static boolean isParsable(Object parser, String str) {
    Class theClass = (parser instanceof Class? (Class)parser: parser.getClass());
    boolean staticOnly = (parser == theClass), foundAtLeastOne = false;
    Method[] methods = theClass.getMethods();

    // Loop over methods
    for (int index = 0; index < methods.length; index++) {
        Method method = methods[index];

        // If method starts with parse, is public and has one String parameter.
        // If the parser parameter was a Class, then also ensure the method is static. 
        if(method.getName().startsWith("parse") &&
            (!staticOnly || Modifier.isStatic(method.getModifiers())) &&
            Modifier.isPublic(method.getModifiers()) &&
            method.getGenericParameterTypes().length == 1 &&
            method.getGenericParameterTypes()[0] == String.class)
        {
            try {
                foundAtLeastOne = true;
                method.invoke(parser, str);
                return true; // Successfully parsed without exception
            } catch (Exception exception) {
                // If invoke problem, try a different method
                /*if(!(exception instanceof IllegalArgumentException) &&
                   !(exception instanceof IllegalAccessException) &&
                   !(exception instanceof InvocationTargetException))
                        continue; // Look for other parse methods*/

                // Parse method refuses to parse, look for another different method
                continue; // Look for other parse methods
            }
        }
    }

    // No more accessible parse method could be found.
    if(foundAtLeastOne) return false;
    else throw new RuntimeException(new NoSuchMethodException());
}


/**
 * METHOD: willParse<p><p>
 * 
 * A convienence method which calls the isParseable method, but does not throw any exceptions
 * which could be thrown through programatic errors.<p>
 * 
 * Use of {@link #isParseable(Object, String) isParseable} is recommended for use so programatic
 * errors can be caught in development, unless the value of the <code>parser</code> parameter is
 * unpredictable, or normal programtic exceptions should be ignored.<p>
 * 
 * See {@link #isParseable(Object, String) isParseable} for full description of method
 * usability.<p>
 * 
 * @param parser    The Class type or instantiated Object to find a parse method in.
 * @param str   The String you want to parse
 * 
 * @return true if a parse method was found and completed without exception
 * @see #isParseable(Object, String) for full description of method usability 
 */
public static boolean willParse(Object parser, String str) {
    try {
        return isParsable(parser, str);
    } catch(Throwable exception) {
        return false;
    }
}

答案 13 :(得分:5)

例外是昂贵的,但在这种情况下,RegEx需要更长的时间。下面的代码显示了两个函数的简单测试 - 一个使用异常,一个使用正则表达式。在我的机器上,RegEx版本比异常慢10倍。

import java.util.Date;


public class IsNumeric {

public static boolean isNumericOne(String s) {
    return s.matches("-?\\d+(\\.\\d+)?");  //match a number with optional '-' and decimal.      
}

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

public static void main(String [] args) {

    String test = "12345.F";

    long before = new Date().getTime();     
    for(int x=0;x<1000000;++x) {
        //isNumericTwo(test);
        isNumericOne(test);
    }
    long after = new Date().getTime();

    System.out.println(after-before);

}

}

答案 14 :(得分:5)

  

正则表达匹配

这是升级的另一个例子&#34; CraigTP&#34;正则表达式与更多验证匹配。

public static boolean isNumeric(String str)
{
    return str.matches("^(?:(?:\\-{1})?\\d+(?:\\.{1}\\d+)?)$");
}
  1. 只允许一个负号 - 并且必须在开头。
  2. 负号后必须有数字。
  3. 只允许一个小数符号
  4. 小数点后必须有数字。
  5.   

    正则表达式测试

    1                  --                   **VALID**
    1.                 --                   INVALID
    1..                --                   INVALID
    1.1                --                   **VALID**
    1.1.1              --                   INVALID
    
    -1                 --                   **VALID**
    --1                --                   INVALID
    -1.                --                   INVALID
    -1.1               --                   **VALID**
    -1.1.1             --                   INVALID
    

答案 15 :(得分:5)

要仅匹配仅包含ASCII数字的正十进制整数,请使用:

public static boolean isNumeric(String maybeNumeric) {
    return maybeNumeric != null && maybeNumeric.matches("[0-9]+");
}

答案 16 :(得分:5)

这是我的类,用于检查字符串是否为数字。它还修复了数字字符串:

特点:

  1. 删除不必要的零[“12.0000000” - &gt; “12”]
  2. 删除不必要的零[“12.0580000” - &gt; “12.058”]
  3. 删除非数字字符[“12.00sdfsdf00” - &gt; “12”]
  4. 处理负字符串值[“-12,020000” - &gt; “-12.02”]
  5. 删除多个点[“-12.0.20.000” - &gt; “-12.02”]
  6. 没有额外的库,只是标准的Java
  7. 你去......

    public class NumUtils {
        /**
         * Transforms a string to an integer. If no numerical chars returns a String "0".
         *
         * @param str
         * @return retStr
         */
        static String makeToInteger(String str) {
            String s = str;
            double d;
            d = Double.parseDouble(makeToDouble(s));
            int i = (int) (d + 0.5D);
            String retStr = String.valueOf(i);
            System.out.printf(retStr + "   ");
            return retStr;
        }
    
        /**
         * Transforms a string to an double. If no numerical chars returns a String "0".
         *
         * @param str
         * @return retStr
         */
        static String makeToDouble(String str) {
    
            Boolean dotWasFound = false;
            String orgStr = str;
            String retStr;
            int firstDotPos = 0;
            Boolean negative = false;
    
            //check if str is null
            if(str.length()==0){
                str="0";
            }
    
            //check if first sign is "-"
            if (str.charAt(0) == '-') {
                negative = true;
            }
    
            //check if str containg any number or else set the string to '0'
            if (!str.matches(".*\\d+.*")) {
                str = "0";
            }
    
            //Replace ',' with '.'  (for some european users who use the ',' as decimal separator)
            str = str.replaceAll(",", ".");
            str = str.replaceAll("[^\\d.]", "");
    
            //Removes the any second dots
            for (int i_char = 0; i_char < str.length(); i_char++) {
                if (str.charAt(i_char) == '.') {
                    dotWasFound = true;
                    firstDotPos = i_char;
                    break;
                }
            }
            if (dotWasFound) {
                String befDot = str.substring(0, firstDotPos + 1);
                String aftDot = str.substring(firstDotPos + 1, str.length());
                aftDot = aftDot.replaceAll("\\.", "");
                str = befDot + aftDot;
            }
    
            //Removes zeros from the begining
            double uglyMethod = Double.parseDouble(str);
            str = String.valueOf(uglyMethod);
    
            //Removes the .0
            str = str.replaceAll("([0-9])\\.0+([^0-9]|$)", "$1$2");
    
            retStr = str;
    
            if (negative) {
                retStr = "-"+retStr;
            }
    
            return retStr;
    
        }
    
        static boolean isNumeric(String str) {
            try {
                double d = Double.parseDouble(str);
            } catch (NumberFormatException nfe) {
                return false;
            }
            return true;
        }
    
    }
    

答案 17 :(得分:5)

一种表现良好的方法,避免尝试捕捉和处理负数和科学记数法。

Pattern PATTERN = Pattern.compile( "^(-?0|-?[1-9]\\d*)(\\.\\d+)?(E\\d+)?$" );

public static boolean isNumeric( String value ) 
{
    return value != null && PATTERN.matcher( value ).matches();
}

答案 18 :(得分:4)

//请查看以下代码

public static boolean isDigitsOnly(CharSequence str) {
    final int len = str.length();
    for (int i = 0; i < len; i++) {
        if (!Character.isDigit(str.charAt(i))) {
            return false;
        }
    }
    return true;
}

答案 19 :(得分: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;
}

答案 20 :(得分: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;
    }
}

答案 21 :(得分:3)

您可以使用java.util.Scanner对象。

public static boolean isNumeric(String inputData) {
      Scanner sc = new Scanner(inputData);
      return sc.hasNextInt();
    }

答案 22 :(得分:2)

解析它(即使用Integer#parseInt)并简单地捕获异常。 =)

澄清一下:parseInt函数检查它是否可以在任何情况下解析数字(显然),如果你想要解析它,你不会通过实际解析来获得任何性能损失。

如果您不想解析它(或者非常极少地解析它),您当然可能希望以不同方式进行解析。

答案 23 :(得分: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

答案 24 :(得分: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.
}

答案 25 :(得分:2)

您可以使用Apache Commons Lang中的NumberUtils.isCreatable()。

由于NumberUtils.isNumber将在4.0中弃用,因此请改用NumberUtils.isCreatable()。

答案 26 :(得分:1)

如果字符串可能包含小数,则可以使用BigDecimal

try {
    new java.math.BigInteger(testString);
} catch(NumberFormatException e) {
    throw new RuntimeException("Not a valid number");
}

答案 27 :(得分:1)

基于其他答案,我写了自己的答案,它不使用模式或使用异常检查进行解析。

最多检查一个减号,最多检查一个小数点。

以下是一些示例及其结果:

“ 1”,“-1”,“-1.5”和“ -1.556”返回true

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

注意:如果需要,您可以修改此参数以接受Locale参数,并将其传递给DecimalFormatSymbols.getInstance()调用,以使用特定的Locale代替当前的Locale。

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

答案 28 :(得分:1)

如果您使用以下方法进行检查:

public static boolean isNumeric(String str) {
    NumberFormat formatter = NumberFormat.getInstance();
    ParsePosition pos = new ParsePosition(0);
    formatter.parse(str, pos);
    return str.length() == pos.getIndex();
}

然后,很长的String输入发生了什么,例如我称之为此方法:

System.out.println(isNumeric("94328948243242352525243242524243425452342343948923"));

结果为“ true”,也是一个太大的数字! 如果使用正则表达式进行检查,将会发生同样的事情! 因此,我宁愿使用“解析”方法进行检查,如下所示:

public static boolean isNumeric(String str) {
    try {
        int number = Integer.parseInt(str);
        return true;
    } catch (Exception e) {
        return false;
    }
}

结果就是我所期望的!

答案 29 :(得分:1)

我已经说明了在不使用任何API的情况下检查数字和小数的一些条件,

检查固定长度1位数

Character.isDigit(char)

检查固定长度编号(假设长度为6)

String number = "132452";
if(number.matches("([0-9]{6})"))
System.out.println("6 digits number identified");

检查(假设4到6个长度)

之间的变化长度数
//  {n,m}  n <= length <= m
String number = "132452";
if(number.matches("([0-9]{4,6})"))
System.out.println("Number Identified between 4 to 6 length");

String number = "132";
if(!number.matches("([0-9]{4,6})"))
System.out.println("Number not in length range or different format");

检查(假设4到7长度)

之间的变化长度十进制数
//  It will not count the '.' (Period) in length
String decimal = "132.45";
if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Numbers Identified between 4 to 7");

String decimal = "1.12";
if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Numbers Identified between 4 to 7");

String decimal = "1234";
if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Numbers Identified between 4 to 7");

String decimal = "-10.123";
if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Numbers Identified between 4 to 7");

String decimal = "123..4";
if(!decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Decimal not in range or different format");

String decimal = "132";
if(!decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Decimal not in range or different format");

String decimal = "1.1";
if(!decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Decimal not in range or different format");

希望它会帮助很多人。

答案 30 :(得分:1)

使用IntStream

并行检查非常长字符串

在Java 8中,以下测试给定string的所有字符是否在&#39; 0&#39;到&#39; 9&#39;请注意接受空字符串:

string.chars().unordered().parallel().allMatch( i -> '0' <= i && '9' >= i )

答案 31 :(得分:1)

这是我知道检查String是否为数字的最快方式:

select * from
(select child as enfant,title as libelle, COALESCE(parent ,child) as Parent  
from tree2) as tree2  
order by COALESCE(parent , 1),parent,enfant

答案 32 :(得分:1)

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

答案 33 :(得分:1)

以下两种方法可行。 (不使用例外)。 注意:Java默认为pass-by-value,String的值是String的对象数据的地址。 所以,当你在做什么时

stringNumber = stringNumber.replaceAll(" ", "");

您已将输入值更改为没有空格。 如果需要,可以删除该行。

private boolean isValidStringNumber(String stringNumber)
{
    if(stringNumber.isEmpty())
    {
        return false;
    }

    stringNumber = stringNumber.replaceAll(" ", "");

    char [] charNumber = stringNumber.toCharArray();
    for(int i =0 ; i<charNumber.length ;i++)
    {
        if(!Character.isDigit(charNumber[i]))
        {
            return false;
        }
    }
    return true;
}

如果您想允许浮动,这是另一种方法 据称这种方法允许表格中的数字通过 1,123,123,123,123,123.123 我刚刚做到了,我认为需要进一步测试才能确保它正常运行。

private boolean isValidStringTrueNumber(String stringNumber)
{
    if(stringNumber.isEmpty())
    {
        return false;
    }

    stringNumber = stringNumber.replaceAll(" ", "");
    int countOfDecimalPoint = 0;
    boolean decimalPointPassed = false;
    boolean commaFound = false;
    int countOfDigitsBeforeDecimalPoint = 0;
    int countOfDigitsAfterDecimalPoint =0 ;
    int commaCounter=0;
    int countOfDigitsBeforeFirstComma = 0;

    char [] charNumber = stringNumber.toCharArray();
    for(int i =0 ; i<charNumber.length ;i++)
    {
        if((commaCounter>3)||(commaCounter<0))
        {
            return false;
        }
        if(!Character.isDigit(charNumber[i]))//Char is not a digit.
        {
            if(charNumber[i]==',')
            {
                if(decimalPointPassed)
                {
                    return false;
                }
                commaFound = true;
                //check that next three chars are only digits.
                commaCounter +=3;
            }
            else if(charNumber[i]=='.')
            {
                decimalPointPassed = true;
                countOfDecimalPoint++;
            }
            else
            {
                return false;
            }
        }
        else //Char is a digit.
        {
            if ((commaCounter>=0)&&(commaFound))
            {
                if(!decimalPointPassed)
                {
                    commaCounter--;
                }
            }

            if(!commaFound)
            {
                countOfDigitsBeforeFirstComma++;
            }

            if(!decimalPointPassed)
            {
                countOfDigitsBeforeDecimalPoint++;
            }
            else
            {
                countOfDigitsAfterDecimalPoint++;
            }
        }
    }
    if((commaFound)&&(countOfDigitsBeforeFirstComma>3))
    {
        return false;
    }
    if(countOfDecimalPoint>1)
    {
        return false;
    }

    if((decimalPointPassed)&&((countOfDigitsBeforeDecimalPoint==0)||(countOfDigitsAfterDecimalPoint==0)))
    {
        return false;
    }
    return true;
}

答案 34 :(得分:0)

试试这个:

public  boolean isNumber(String str)
{       
    short count = 0;
    char chc[]  = {'0','1','2','3','4','5','6','7','8','9','.','-','+'};
    for (char c : str.toCharArray())
    {   
        for (int i = 0;i < chc.length;i++)
        {
            if( c  == chc[i]){
                count++;        
            }
         }                      
    }
    if (count != str.length() ) 
        return false;
    else
        return true;
}

答案 35 :(得分:0)

我认为可靠地判断字符串是否为数字的唯一方法是解析它。所以我只是解析它,如果它是一个数字,你可以免费获得一个int中的数字!

答案 36 :(得分:0)

如果你想使用正则表达式进行检查,你应该创建一个最终的静态Pattern对象,这样只需要编译一次正则表达式。编译正则表达式只需要执行匹配,因此通过采取这种预防措施,您可以将方法的执行时间减半。

final static Pattern NUMBER_PATTERN = Pattern.compile("[+-]?\\d*\\.?\\d+");

static boolean isNumber(String input) {
    Matcher m = NUMBER_PATTERN.matcher(input);
    return m.matches();
}

我假设一个数字是一个字符串,其中只有十进制数字,开头可能是+或 - 符号,最多只有一个小数点(不是最后一个)而没有其他字符(包括逗号) ,空格,其他计数系统中的数字,罗马数字,象形文字)。

这个解决方案非常简洁,速度非常快,但你可以像这样做,每百万次调用可以节省几毫秒

static boolean isNumber(String s) {
    final int len = s.length();
    if (len == 0) {
        return false;
    }
    int dotCount = 0;
    for (int i = 0; i < len; i++) {
        char c = s.charAt(i);
        if (c < '0' || c > '9') {
            if (i == len - 1) {//last character must be digit
                return false;
            } else if (c == '.') {
                if (++dotCount > 1) {
                    return false;
                }
            } else if (i != 0 || c != '+' && c != '-') {//+ or - allowed at start
                return false;
            }

        }
    }
    return true;
}

答案 37 :(得分:-1)

String text="hello 123";
if(Pattern.matches([0-9]+))==true
System.out.println("String"+text);

答案 38 :(得分:-3)

import java.util.Scanner;

public class TestDemo {
    public static void main(String[] args) {
        boolean flag = true;
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter the String:");
        String str = sc.nextLine();

        for (int i = 0; i < str.length(); i++) {
            if(str.charAt(i) > 48 && str.charAt(i) < 58) {
                flag = false;
                break;
            }
        }

        if(flag == true) {
            System.out.println("String is a valid String.");
        } else {
            System.out.println("String contains number.");
        }
    }
}