解析非负双打

时间:2010-08-30 14:10:05

标签: java string parsing double number-formatting

我需要的函数将采用字符串和整数来表示非负二元组或整数的位置并返回Number或null。如果有'+'则返回null。

实施例

2.1      , 0 -> 2.1
+2.1     , 0 -> null
-1       , 0 -> null
-1.2     , 1 -> 1.2
qwa56sdf , 3 -> 56

最优雅的方法是什么? 感谢。

UPD 我需要这样的代码,但更好)

    Number parse(String str, int pos){
        Matcher m = Pattern.compile("^(\\d+(?:\\.\\d+)?)").matcher(str);
        m.region(pos, str.length());
        if(m.find()){
            return Double.parseDouble(m.group());
        } else {
            return null;
        }
    }

6 个答案:

答案 0 :(得分:3)

你可以尝试:

public static void main(String[] args) {
  System.out.println(parse("2.1", 0));
  System.out.println(parse("+2.1", 0));
  System.out.println(parse("-1", 0));
  System.out.println(parse("-1.2", 1));
  System.out.println(parse("qwa56sdf", 3));
}

private static Double parse(String string, int index) {
  if (string.charAt(index) == '-' || string.charAt(index) == '+') {
    return null;
  }
  try {
    return Double.parseDouble(string.substring(index).replaceAll("[^\\d.]", ""));
  }
  catch (NumberFormatException e) {
    return null;
  }
}

我必须使用replace all删除尾随的非数字字符,因为它们导致了NumberFormatException,并且对于像上一个示例中的输入那样返回null。

编辑: 您为评论中的案例工作的其他选项可能是检查每个字符

private static Double parse(String string, int index) {
    String finalString = "";
    boolean foundSeparator = false;
    for (char c : string.substring(index).toCharArray()) {
        if (c == '.') {
            if (foundSeparator) {
                break;
            }
            else {
                foundSeparator = true;
            }
        }
        else if (!Character.isDigit(c)) {
            break;
        }
        finalString += c;
    }
    if (finalString == "") {
        return null;
    }
    return Double.parseDouble(finalString);
}

答案 1 :(得分:2)

您需要使用String.substring()方法的组合从字符串中指示的位置开始,并使用NumberFormat类来解析数字。

答案 2 :(得分:1)

如果这在功能上是正确的,它对我来说看起来很优雅。您可能希望使Pattern成为最终的类成员,因为您只需要编译一次。该地区可能不需要:

Matcher m = pattern.matcher(str.substring(pos));

另一种选择是从1-char-length子字符串开始并将其增长直到​​它不再解析为止:

if ( str.charAt(pos) == '+' || str.charAt(pos) == '-' ) {
    //special cases
    return null;
}
Double val = null;
for ( int i = pos+1; i <= str.length(); i++ ) {
    try {
       val = Double.parseDouble(str.substring(pos, i)) {
    }  catch (NumberFormatException e) {
       break;
    }
}
return val;

它有点简单,但也很天真。一个不太可读但性能更高的解决方案就是在通过一次查看一个字符来解析之前找到双尾的结尾。

答案 3 :(得分:1)

还有Scanner课程。其中特别具有读取基元的方法,例如scanner.hasNextDouble()scanner.nextDouble()。你仍然需要检查+或 - ,因为那仍然会通过检查。

答案 4 :(得分:1)

public static Double parseDouble(String input, int fromIndex) {
    Matcher matcher = Pattern.compile("\\d*\\.?\\d+")
        .matcher(input.substring(fromIndex));
    return matcher.lookingAt() ? Double.parseDouble(matcher.group()) : null;
}

答案 5 :(得分:1)

我认为以下实施对您的要求更为优雅。我正在使用java.text.NumberFormat类进行解析。

    private static Number parse(String text, int position){
        Number value=null;
        NumberFormat nf = NumberFormat.getInstance();
        try {
            value = nf.parse(text,new ParsePosition(position));
            if (value.intValue() < 0)
                value = null;
        } catch (Exception e) {
            value = null;
        }
        return value;
   }