Java 如何找出字符串中包含的值是否为双精度值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3133770/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 16:44:16  来源:igfitidea点击:

How to find out if the value contained in a string is double or not

java

提问by Gauranga

In Java, I am trying to find out if the value contained in a string is double or not?

在 Java 中,我试图找出字符串中包含的值是否为双精度值?

回答by Uri

You could attempt to parse it with Double.parseDouble(String s)

你可以尝试解析它 Double.parseDouble(String s)

This will return the double if parsing was successful and an an exception if it is not parseable.

如果解析成功,这将返回双精度值,如果无法解析则返回异常。

So you could wrap the whole thing in a function that contains a try-catch, and return false if you got an exception or true if you got an actual value.

因此,您可以将整个内容包装在一个包含 try-catch 的函数中,如果出现异常则返回 false,如果得到实际值则返回 true。

回答by Hendrik Brummermann

public boolean isDouble(String value) {
    try {
        Double.parseDouble(value);
        return true;
    } catch (NumberFormatException e) {
        return false;
    }
}

回答by unbeli

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

回答by Robby Pond

    public boolean isDouble( String input )  
    {  
       try  
       {  
          Double.parseDouble( input );  
          return true;  
       }  
       catch( Exception e)  
       {  
         return false;  
      }  
  }  

回答by lindiand

I would suggest this:

我建议这样做:

try {
  d = Double.parseDouble(myString);
}
catch (NumberFormatException ex) {
    // Do something smart here...
}

回答by Mark Peters

Others have speculated that you might want to also know that the input is NOT expressed as an integer. Depending on your requirements, this might do the job quick and dirty:

其他人推测您可能还想知道输入不表示为整数。根据您的要求,这可能会快速而肮脏地完成工作:

public static void main(String[] args) throws Exception {
    System.out.println(isNonIntegerDouble("12"));  //false
    System.out.println(isNonIntegerDouble("12.1")); //true
    System.out.println(isNonIntegerDouble("12.0")); //true
}

public static boolean isNonIntegerDouble(String in) {
    try {
        Double.parseDouble(in);
    } catch (NumberFormatException nfe) {
        return false;
    }
    try {
        new BigInteger(in);
    } catch (NumberFormatException nfe) {
        return true;
    }
    return false;
}

At this point I feel string matching would be a more suitable choice, however.

然而,在这一点上,我觉得字符串匹配将是一个更合适的选择。

回答by aioobe

There is a note about this in the source for Double:

源代码中Double有一个关于此的注释:

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

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

The final form of the regular expressions that follows is quite long:

下面的正则表达式的最终形式很长:

[\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]*

Using this method however, you can easily exclude some special doubles such as Infinityand NaNwhich are both accepted by Double.parseDouble. For example like this:

但是,使用此方法,您可以轻松排除一些特殊的双打,例如InfinityNaN,它们都被 接受Double.parseDouble。例如像这样:

String regExp = "[\x00-\x20]*[+-]?(((((\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 matches = yourString.matches(regExp);

回答by Pascal Thivent

You could create a Scanner(String)and use the hasNextDouble()method. From its javadoc:

您可以创建一个Scanner(String)并使用该hasNextDouble()方法。从它的javadoc:

Returns trueif the next token in this scanner's input can be interpreted as a double value using the nextDouble()method. The scanner does not advance past any input.

返回true此扫描器输入中的下一个标记是否可以使用该nextDouble()方法解释为双精度值。扫描仪不会通过任何输入。

For example, this snippet:

例如,这个片段:

List<String> values = Arrays.asList("foo", "1", "2.3", "1f", "0.2d", "3.14");
for (String source : values) {
    Scanner scanner = new Scanner(source);
    System.out.println(String.format("%4s: %s", source, scanner.hasNextDouble()));
}

Would produce the following output:

将产生以下输出:

 foo: false
   1: true
 2.3: true
  1f: false
0.2d: false
3.14: true

回答by KLee1

You could use the following regex on the string:

您可以在字符串上使用以下正则表达式:

[-+]?[0-9]*\.?[0-9]*

and see if it matches.

看看它是否匹配。

回答by Bill the Lizard

Using a Scannerwill be significantly slower than using Double.parseDouble(String s).

使用 aScanner会比使用 慢得多Double.parseDouble(String s)

private static Random rand = new Random();
private static final String regExp = "[\x00-\x20]*[+-]?(((((\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]*";
private static final Pattern pattern = Pattern.compile(regExp);

public static void main(String[] args) {

    int trials = 50000;
    String[] values = new String[trials];

    // initialize the array
    // about half the values will be parsable as double
    for( int i = 0; i < trials; ++i ) {
        double d = rand.nextDouble();
        boolean b = rand.nextBoolean();

        values[i] = (b ? "" : "abc") + d;
    }

    long start = System.currentTimeMillis();

    int parseCount = 0;
    for( int i = 0; i < trials; ++i ) {
        if( isDoubleParse(values[i]) ) {
            parseCount++;
        }
    }

    long end = System.currentTimeMillis();
    long elapsed = end - start;

    System.out.println("Elapsed time parsing: " + elapsed + " ms");
    System.out.println("Doubles: " + parseCount);

    // reset the timer for the next run
    start = System.currentTimeMillis();

    int scanCount = 0;
    for( int i = 0; i < trials; ++i ) {
        if( isDoubleScan(values[i]) ) {
            scanCount++;
        }
    }

    end = System.currentTimeMillis();
    elapsed = end - start;

    System.out.println("Elapsed time scanning: " + elapsed + " ms");
    System.out.println("Doubles: " + scanCount);


    // reset the timer for the next run
    start = System.currentTimeMillis();

    int regexCount = 0;
    for( int i = 0; i < trials; ++i ) {
        if( isDoubleRegex(values[i]) ) {
            regexCount++;
        }
    }

    end = System.currentTimeMillis();
    elapsed = end - start;

    System.out.println("Elapsed time regex (naive): " + elapsed + " ms");
    System.out.println("Doubles: " + naiveRegexCount);


    // reset the timer for the next run
    start = System.currentTimeMillis();

    int compiledRegexCount = 0;
    for( int i = 0; i < trials; ++i ) {
        if( isDoubleCompiledRegex(values[i]) ) {
            compiledRegexCount++;
        }
    }

    end = System.currentTimeMillis();
    elapsed = end - start;

    System.out.println("Elapsed time regex (compiled): " + elapsed + " ms");
    System.out.println("Doubles: " + compiledRegexCount);
}


public static boolean isDoubleParse(String s) {
    if( s == null ) return false;
    try {
        Double.parseDouble(s);
        return true;
    } catch (NumberFormatException e) {
        return false;
    }
}

public static boolean isDoubleScan(String s) {
    Scanner scanner = new Scanner(s);
    return scanner.hasNextDouble();
}

public static boolean isDoubleRegex(String s) {
    return s.matches(regExp);
}

public static boolean isDoubleCompiledRegex(String s) {
    Matcher m = pattern.matcher(s);
    return m.matches();
}

When I run the code above I get the following output:

当我运行上面的代码时,我得到以下输出:

Elapsed time parsing: 235 ms
Doubles: 24966
Elapsed time scanning: 31358 ms
Doubles: 24966
Elapsed time regex (naive): 1829 ms
Doubles: 24966
Elapsed time regex (compiled): 109 ms
Doubles: 24966

经过的时间解析:235 ms
双打:24966
经过的时间扫描:
31358 ms双打:24966
经过的时间正则表达式(天真):1829 ms
双打:24966
经过的时间正则表达式(编译):109
ms9 双打662:

The regular expression method runs fairly quickly given the complexity of the regex, but still not quite as fast as simply parsing using Double.parseDouble(s). As pointed out in the comments, there are a few values like NaNthat get past the parser that probably shouldn't.

鉴于正则表达式的复杂性,正则表达式方法运行得相当快,但仍然不如简单地使用Double.parseDouble(s). 正如评论中指出的那样,有一些类似的值NaN可能不应该通过解析器。

Update:

更新:

Pre-compiling the regular expression as suggested by @Gabemakes all the difference. The compiled regex method is now the clear winner.

按照@ Gabe 的建议预编译正则表达式会使一切变得不同。编译后的正则表达式方法现在是明显的赢家。