我使用以下逻辑从String中提取double值。它在第一个String上工作正常但在第二个String上引发异常。引发的异常为java.util.NoSuchElementException
。
public class StringHandling {
public String processString(String string)
{
Scanner st = new Scanner(string);
while (!st.hasNextDouble())
{
st.next();
}
double value = st.nextDouble();
return String.valueOf(value);
}
public static void main(String[] args)
{
String first = "Hey, he is 70.3 miles away.";
String second = "{\"Hey\", \"he\" \"is\": 1.0, \"miles\" away}";
StringHandling sh = new StringHandling();
System.out.println("First Value is "+sh.processString(first));
System.out.println("Second Value is "+sh.processString(second));
}
}
我只是想知道为什么它会引发异常。
答案 0 :(得分:3)
这是问题所在:
"{\"Hey\", \"he\" \"is\": 1.0, \"miles\" away}"
默认情况下,类next
的{{1}}方法会为您提供下一个输入,直到达到空格。
Scanner
方法可以像这样获取它:
next
在这种情况下,您有{"Hey",
"he"
"is":
1.0,
"miles"
away}
不 a 1.0,
(请注意逗号)。
这就是为什么你得到double
的原因:你继续NoSuchElementException
,但是找不到st.next()
,所以字符串的结尾到了,而且扫描器没有找不到其他元素。
答案 1 :(得分:0)
您可以使用正则表达式而不是扫描程序:
public String processString(String string) {
Pattern p = Pattern.compile("(\\d+(?:\\.\\d+))");
Matcher m = p.matcher(string);
while(m.find()) {
return m.group(1);
}
return null;
}
答案 2 :(得分:0)
默认情况下,Scanner
分隔在空白处。因此,您的第二个示例将1.0,
视为输入之一,它不会将其识别为double。
您的代码还假设您将退出while循环,因为您找到了double。在这种情况下,没有值可读,所以你得到一个例外。
一种选择是更改Scanner
对象使用的分隔符。也许是这样的:
st.useDelimiter("[^\\w.]");
这会将您的输入分为“单词”,其中包含字母数字字符,下划线和句号的任意组合。
您可以使用正则表达式找到此值。下面的示例查找包含小数点和至少一个小数位的数字:
public static String findWithRegex(String string) {
Pattern pattern = Pattern.compile("\\d+\\.\\d+");
Matcher matcher = pattern.matcher(string);
if (matcher.find()) {
return matcher.group();
} else {
// do something more useful here
return "none";
}
}