当前位置:  开发笔记 > 编程语言 > 正文

最优雅的方法来检测String是否是一个数字?

如何解决《最优雅的方法来检测String是否是一个数字?》经验,为你挑选了4个好方法。

是否有更好,更优雅(和/或可能更快)的方式

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

...?


编辑:因为我不能选择两个答案我正在使用正则表达式,因为a)它优雅而且b)说"Jon Skeet解决了问题"是一个重言式,因为Jon Skeet本身就是所有问题的解决方案.



1> Jon Skeet..:

我不相信Java中有任何内容可以更快,更可靠地完成它,假设稍后您将要使用Double.valueOf(或类似)实际解析它.

我会使用Double.parseDouble而不是Double.valueOf来避免不必要地创建一个Double,并且你还可以通过检查数字,e/E,和来更快地摆脱明显愚蠢的数字.预先.所以,像:

public boolean isDouble(String value)
{        
    boolean seenDot = false;
    boolean seenExp = false;
    boolean justSeenExp = false;
    boolean seenDigit = false;
    for (int i=0; i < value.length(); i++)
    {
        char c = value.charAt(i);
        if (c >= '0' && c <= '9')
        {
            seenDigit = true;
            continue;
        }
        if ((c == '-' || c=='+') && (i == 0 || justSeenExp))
        {
            continue;
        }
        if (c == '.' && !seenDot)
        {
            seenDot = true;
            continue;
        }
        justSeenExp = false;
        if ((c == 'e' || c == 'E') && !seenExp)
        {
            seenExp = true;
            justSeenExp = true;
            continue;
        }
        return false;
    }
    if (!seenDigit)
    {
        return false;
    }
    try
    {
        Double.parseDouble(value);
        return true;
    }
    catch (NumberFormatException e)
    {
        return false;
    }
}

请注意,尽管尝试了几次,但仍然不包括"NaN"或十六进制值.是否希望这些传递取决于上下文.

根据我的经验,正则表达式比上面的硬编码检查慢.



2> 小智..:

你可以使用正则表达式,即类似的东西String.matches("^[\\d\\-\\.]+$");(如果你没有测试负数或浮点数,你可以简化一点).

不确定这是否会比你概述的方法更快.

编辑:鉴于所有这些争议,我决定进行测试并获得一些有关这些方法的速度的数据.不是那么正确,而是他们跑得多快.

您可以在我的博客上阅读我的结果.(提示:Jon Skeet FTW).



3> Ran Biron..:

请参阅java.text.NumberFormat(javadoc).

NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
Number myNumber = nf.parse(myString);
int myInt = myNumber.intValue();
double myDouble = myNumber.doubleValue();



4> Michael Myer..:

正确的正则表达式实际上是在Double javadocs中给出的:

为了避免在无效字符串上调用此方法并抛出NumberFormatException,可以使用下面的正则表达式来筛选输入字符串:

    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
    }

但是,这不允许本地化表示:

要解释浮点值的本地化字符串表示形式,请使用NumberFormat的子类.

推荐阅读
TXCWB_523
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有