使用正则表达式运行计算器程序时出现NumberFormatException

时间:2018-06-20 13:15:26

标签: java regex numberformatexception

我正在尝试编写一个简单的计算器。

public static String cal(){
        String a="-60-1+40";
        if(a.matches("-?[1-9][0-9]?([\\+-][1-9][0-9]?)+")){
            System.out.println(a);
            String operators[]=a.split("[0-9]+");
            String operands[]=a.split("[+-]");
            int agregate = Integer.parseInt(operands[0]);
            for(int i=1;i<operands.length;i++){
                if(operators[i].equals("+"))
                    agregate += Integer.parseInt(operands[i]);
                else 
                    agregate -= Integer.parseInt(operands[i]);
            }
             return Integer.toString(agregate);
        }else throw new invalidExpressionException(a+" is a Invalid expression");
    }

我具有此功能,但是当我尝试运行它时,如果字符串的第一个字符是NumberFormatException,则会得到一个"-"。所有其他情况似乎都是正确的,只有那一种失败了。我已经尝试修复了一段时间,但找不到方法。

run:
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
-60-1+40
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:592)
    at java.lang.Integer.parseInt(Integer.java:615)
    at calculator.Calculator.cal(Calculator.java:20)
    at calculator.Calculator.main(Calculator.java:9)

3 个答案:

答案 0 :(得分:1)

尝试一下。

public static String calculator(){
    String a="-60-1+40";
    if(a.matches("-?[1-9][0-9]?([\\+-][1-9][0-9]?)+")){
        System.out.println(a);
        String operators[]=a.split("[0-9]+");
        String operands[]=a.split("[+-]");
        int agregate = operands[0].isEmpty() ? 0 : Integer.parseInt(operands[0]);//changed code
        for(int i=1;i<operators.length;i++){//operators.length is better
            if(operators[i].equals("+"))
                agregate += Integer.parseInt(operands[i]);
            else 
                agregate -= Integer.parseInt(operands[i]);
        }
         return Integer.toString(agregate);
    }
    return a;
}

答案 1 :(得分:1)

在@Ben的注释之后,一种变通方法是检查第一个字符是否为'-',在这种情况下,在处理字符串之前将0附加在字符串上(-n可以是通过将数字n从0减去而获得):

-1+2-3,应成为0-1+2-3

if(a.startsWith("-")){
    a = "0" + a;
}

答案 2 :(得分:1)

简短答案

简短的答案是,您可以像这样过滤掉空字符串。 Streams是相对较新的API,编写它们可能很棘手。但是,我相信它们很容易阅读。所以这里是:

        String operands[] = Arrays.stream(calculateCommand.split("[+-]"))
                .filter(str -> str != null && 0 < str.trim().length()) // skipping the empty elements
                .toArray(String[]::new);

提示答案

public static String cal() {
    String a = "-60-1+40"; // a reminder for the developer
    return "-21"; // a correct answer for the input above
}

这里有一个拖钓的答案。只要函数始终返回相同的值,就可以继续使用此快捷方式:

返工

以上任何修补程序都无法满足您的需求。我放弃修复该方法。相反,我编写了另一个函数:

// letting the reader know that this calculator can deal with + and - only
public static String additiveCalculator(String calculateCommand) {
    if (calculateCommand == null) {
        // input handling
        throw new NullPointerException("cannot calculate null string");
    }
    if (calculateCommand.startsWith("-")) {
        // dealing with only one case
        return additiveCalculator("0" + calculateCommand);
    }
    if (! calculateCommand.matches("\\d+(\\s*[+-]\\s*\\d+)*")) {
        throw new IllegalArgumentException("Input '" + calculateCommand + "' is not calculable.");
    }
    Integer[] operands = Arrays.stream(calculateCommand.split("[+-]"))
            .map(str -> str.trim())
            .map(str -> Integer.parseInt(str))
            .toArray(Integer[]::new);
    String[] operators = calculateCommand.replaceAll("[^+-]", "").split("");
    int aggregate = operands[0];
    for (int i = 0; i < operators.length; i++) {
        int num = operands[i+1];
        String op = operators[i];
        switch (op) {
            case "+":
                aggregate += num;
                break;
            case "-":
                aggregate -= num;
                break;
            default:
                // this can't happen. However, later this exception might be useful
                throw new IllegalStateException("The " + i + "th operator, '" + op + "' is not an additive operator.");
        }
    }
    return Integer.toString(aggregate);
}

我添加了评论以指出改进之处。我想解释一下数字检查器正则表达式。是\\d+(\\s*[+-]\\s*\\d+)*。这是解释:

  • \\d代表数字。与[0-9]
  • 等效
  • \\s代表空白。
  • \\d+正则表达式以数字开头,也可以为零。无需添加^,因为我们使用String.matches()
  • (...)*,然后我们可以看到零个或多个:
  • \\s*[+-]\\s*\\d+-一些空格,一个运算符,另外一些空格,然后是数字