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
How to find out if the value contained in a string is double or not
提问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
NumberFormatException
be 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 Infinity
and NaN
which are both accepted by Double.parseDouble
. For example like this:
但是,使用此方法,您可以轻松排除一些特殊的双打,例如Infinity
和NaN
,它们都被 接受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
true
if the next token in this scanner's input can be interpreted as a double value using thenextDouble()
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 Scanner
will 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 NaN
that 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 的建议预编译正则表达式会使一切变得不同。编译后的正则表达式方法现在是明显的赢家。