Most elegant way to detect if a String is a number?

前端 未结 11 738

Is there a better, more elegant (and/or possibly faster) way than

boolean isNumber = false;
try{
   Double.valueOf(myNumber);
   isNumber = true;
} catch (Nu         


        
相关标签:
11条回答
  • 2020-12-30 12:16

    Following Phill's answer can I suggest another regex?

    String.matches("^-?\\d+(\\.\\d+)?$");
    
    0 讨论(0)
  • 2020-12-30 12:17

    Leveraging off Mr. Skeet:

    private boolean IsValidDoubleChar(char c)
    {
        return "0123456789.+-eE".indexOf(c) >= 0;
    }
    
    public boolean isDouble(String value)
    {
        for (int i=0; i < value.length(); i++)
        {
            char c = value.charAt(i);
            if (IsValidDoubleChar(c))
                continue;
            return false;
        }
        try
        {
            Double.parseDouble(value);
            return true;
        }
        catch (NumberFormatException e)
        {
            return false;
        }
    }
    
    0 讨论(0)
  • 2020-12-30 12:17

    Most of these answers are somewhat acceptable solutions. All of the regex solutions have the issue of not being correct for all cases you may care about.

    If you really want to ensure that the String is a valid number, then I would use your own solution. Don't forget that, I imagine, that most of the time the String will be a valid number and won't raise an exception. So most of the time the performance will be identical to that of Double.valueOf().

    I guess this really isn't an answer, except that it validates your initial instinct.

    Randy

    0 讨论(0)
  • 2020-12-30 12:17

    I prefer using a loop over the Strings's char[] representation and using the Character.isDigit() method. If elegance is desired, I think this is the most readable:

    package tias;
    
    public class Main {
      private static final String NUMERIC = "123456789";
      private static final String NOT_NUMERIC = "1L5C";
    
      public static void main(String[] args) {
        System.out.println(isStringNumeric(NUMERIC));
        System.out.println(isStringNumeric(NOT_NUMERIC));
      }
    
      private static boolean isStringNumeric(String aString) {
        if (aString == null || aString.length() == 0) {
          return false;
        }
        for (char c : aString.toCharArray() ) {
          if (!Character.isDigit(c)) {
            return false;
          }
        }
        return true;
      }
    

    }

    0 讨论(0)
  • 2020-12-30 12:21

    The correct regex is actually given in the Double javadocs:

    To avoid calling this method on an invalid string and having a NumberFormatException be thrown, the regular expression below can be used to screen the input string:

        final String Digits     = "(\\p{Digit}+)";
        final String HexDigits  = "(\\p{XDigit}+)";
        // an exponent is 'e' or 'E' followed by an optionally 
        // signed decimal integer.
        final String Exp        = "[eE][+-]?"+Digits;
        final String fpRegex    =
            ("[\\x00-\\x20]*"+  // Optional leading "whitespace"
             "[+-]?(" + // Optional sign character
             "NaN|" +           // "NaN" string
             "Infinity|" +      // "Infinity" string
    
             // A decimal floating-point string representing a finite positive
             // number without a leading sign has at most five basic pieces:
             // Digits . Digits ExponentPart FloatTypeSuffix
             // 
             // Since this method allows integer-only strings as input
             // in addition to strings of floating-point literals, the
             // two sub-patterns below are simplifications of the grammar
             // productions from the Java Language Specification, 2nd 
             // edition, section 3.10.2.
    
             // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt
             "((("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+
    
             // . Digits ExponentPart_opt FloatTypeSuffix_opt
             "(\\.("+Digits+")("+Exp+")?)|"+
    
       // Hexadecimal strings
       "((" +
        // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt
        "(0[xX]" + HexDigits + "(\\.)?)|" +
    
        // 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt
        "(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" +
    
        ")[pP][+-]?" + Digits + "))" +
             "[fFdD]?))" +
             "[\\x00-\\x20]*");// Optional trailing "whitespace"
    
        if (Pattern.matches(fpRegex, myString))
            Double.valueOf(myString); // Will not throw NumberFormatException
        else {
            // Perform suitable alternative action
        }
    

    This does not allow for localized representations, however:

    To interpret localized string representations of a floating-point value, use subclasses of NumberFormat.

    0 讨论(0)
提交回复
热议问题