在Java中,我试图找出字符串中包含的值是否为double?
答案 0 :(得分:31)
boolean isDouble(String str) {
try {
Double.parseDouble(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
答案 1 :(得分:13)
source for Double
中有关于此的说明:
[...] 为避免在无效字符串上调用此方法并抛出
NumberFormatException
,可以使用下面的正则表达式来筛选输入字符串: [。 ..]
后面的正则表达式的最终形式很长:
[\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]*
但是,使用此方法,您可以轻松地排除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);
答案 2 :(得分:7)
您可以创建Scanner(String)
并使用hasNextDouble()
方法。来自它的javadoc:
如果此扫描仪输入中的下一个标记可以,则返回
true
解释为使用的双值nextDouble()
方法。扫描仪 没有超越任何输入。
例如,此代码段:
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()));
}
会产生以下输出:
foo: false 1: true 2.3: true 1f: false 0.2d: false 3.14: true
答案 3 :(得分:7)
使用Scanner
将明显慢于使用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();
}
当我运行上面的代码时,我得到以下输出:
经过时间分析:235毫秒
双打:24966
经过时间扫描:31358毫秒
双打:24966
经过时间正则表达式(天真):1829毫秒
双打:24966
经过时间正则表达式(编译):109毫秒
双打:24966
由于正则表达式的复杂性,正则表达式方法运行得相当快,但仍然不如使用Double.parseDouble(s)
进行简单解析那么快。正如评论中所指出的那样,有一些像NaN
这样的值可以通过解析器,但可能不应该这样。
根据@ Gabe的建议预编译正则表达式会有所不同。编译的正则表达式方法现在是明显的赢家。
答案 4 :(得分:6)
public boolean isDouble(String value) {
try {
Double.parseDouble(value);
return true;
} catch (NumberFormatException e) {
return false;
}
}
答案 5 :(得分:5)
您可以使用Apache Commons Lang的util类:
NumberUtils.isNumber(aString);
它是安全的,并且不需要使用try-catch块。
注意:用于解析双精度数,如果小数点分隔符是点.
编辑: isNumber已弃用,将从Lang 4.0中删除
最好使用:
NumberUtils.isCreatable(aString);
答案 6 :(得分:2)
您可以尝试使用Double.parseDouble(String s)
如果解析成功则返回double,如果不可解析则返回异常。
因此,您可以将整个事物包装在包含try-catch的函数中,如果有异常则返回false,如果获得实际值则返回true。
答案 7 :(得分:2)
我会建议:
try {
d = Double.parseDouble(myString);
}
catch (NumberFormatException ex) {
// Do something smart here...
}
答案 8 :(得分:2)
其他人猜测你可能也想知道输入没有表示为整数。根据您的要求,这可能会使工作变得快速而且肮脏:
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;
}
此时我觉得字符串匹配是更合适的选择。
答案 9 :(得分:1)
您可以在字符串上使用以下正则表达式:
[-+]?[0-9]*\.?[0-9]*
并查看它是否匹配。
答案 10 :(得分:1)
我们必须处理NumberFormatException和null指针异常,以检查给定的String是数字还是字母数字
public static boolean isNumeric(String strNum) {
try {
Double.parseDouble(strNum);
} catch (NumberFormatException | NullPointerException nfe) {
return false;
}
return true;
}
答案 11 :(得分:0)
我修改了Jonas的isInteger()方法,为我自己的项目提出了方法isDecimal(),我列出了下面的代码。
可能有人可以更改添加更多代码来区分double和float。
虽然我没有检查,它应该很快出来,可能比正则表达更好。唯一的缺陷是在溢出情况等情况下行为不端。
请注意,我在What's the best way to check to see if a String represents an integer in Java?
上提到了Bill的帖子 public boolean isDecimal(String str) {
if (str == null) {
return false;
}
int length = str.length();
if (length == 1 ) {
return false;
}
int i = 0;
if (str.charAt(0) == '-') {
if (length < 3) {
return false;
}
i = 1;
}
int numOfDot = 0;
for (; i < length; i++) {
char c = str.charAt(i);
if (c == '.')
numOfDot++;
else if (c == '/')
return false;
else if (c < '.' || c > '9') {
return false;
}
}
if (numOfDot != 1 )
return false;
return true;
}
答案 12 :(得分:0)
如果您能找到一种方法将数字与字符串隔离,可以使用split方法。然后让我们说deriv()
然后你可以做这样的事情来检查它是否是双倍的。
public static void jsonToMap(String t) throws JSONException {
HashMap<String, String> map = new HashMap<String, String>();
JSONObject jObject = new JSONObject(t);
Iterator<?> keys = jObject.keys();
while( keys.hasNext() ){
String key = (String)keys.next();
String value = jObject.getString(key);
map.put(key, value);
}
System.out.println("json : "+jObject);
System.out.println("map : "+map);
}
答案 13 :(得分:-3)
public boolean isDouble( String input )
{
try
{
Double.parseDouble( input );
return true;
}
catch( Exception e)
{
return false;
}
}