我该如何解析命令行样式输入?

时间:2013-05-12 20:45:06

标签: java parsing text

我正在编写一个用户可以输入类似

的程序
add 5 2

define foo

现在我知道处理这个输入的唯一方法是一堆if / else if语句,即

if(args[0] == "add") add();
else if (args[0] == "define") define();
else print("Command not found.");

是否有更好的方法可以做到这一点,或者某种类型的数据结构/算法是这些类型输入的标准?我特意使用Java,但如果可能的话,我更喜欢与语言无关的答案。谢谢!

4 个答案:

答案 0 :(得分:3)

您可以使用switch声明:

switch (args[0]) {
    case "add":
        // do your adding stuff
        break;
    case "define":
        // do your defining stuff
        break;
    default:
        // command not found
}

switch是大多数语言的常见功能(某些语言使用不同的语法,例如Ruby使用case/when而不是switch/case)。它仅适用于从Java 1.7开始的String

此外,某些语言在变量中有Dictionary和函数,因此例如在Ruby中你可以这样做:

myDictionary = { "add" => someFunctionToAddStuff,
                 "define" => anotherFunction }
myDictionary["define"] # returns anotherFunction

答案 1 :(得分:2)

我在这里做了(坏)假设,你根据你使用args的方式询问命令行参数。但我可能错了。让我知道:

有一种更好的方法可以做到这一点,但您可能需要改变输入的写入方式。事实上,有很多库。这里提到了一些:How to parse command line arguments in Java?以下是一些选项,为了方便而内联:

答案 2 :(得分:2)

设计模式命令可用于此目标。例如:

abstract class Command {
    abstract public String getCommandName();
    abstract public String doAction();
}

要定义自己的函数,只需实现Command class:

class AddCommand extends Command {
    @Override
    public String getCommandName() {
        return "add";
    }

    @Override
    public String doAction() {
        // do your action
    }
}

那么你的主要课程应该是这样的:

public class Main {

    private static Map<String, Command> commands = new HashMap<String, Command>();

    private static void init() {
        Command addCommand = new AddCommand();
        commands.put(addCommand.getCommandName(), addCommand);
    }

    public static void main (String[] args) {
        init();
        if (args[0] != null) {
            Command command = commands.get(args[0]);
            if (command != null) {
                System.out.println(command.doAction());
            } else {
                System.out.println("Command not found");
            }
        }
    }

答案 3 :(得分:1)

根据输入的复杂程度,您可以使用Command和/或Interpreter模式使用手工制作的解决方案,也可以使用免费的XText框架。

如果您的语法不太复杂

解释器 设计模式非常有用,但程序输入符合DSL(域特定语言) 。在您的情况下,输入add 5 2define foo看起来像是较大语法的一部分。如果是这样,请使用 Interpreter 。但是,如果语法很复杂,那么最好的方法是利用像XText这样的DSL生成库

如果你想要解析命令行参数,你应该尝试Apache Commons CLI library

然而,谈到Java,还有一个值得检查的库 - Cliche。它的主要优点是极简单注释驱动模型。请在下面找到一个例子:

// Cliche usage example
public class Calculator {
    @Command
    public void define(String variable) { ... }

    @Command
    public int add(int a, int b) {
        return a + b;
    }

    public static void main(String[] args) throws IOException {
        ShellFactory
          .createConsoleShell("my-prompt", "", new Calculator())
          .commandLoop();
    }
}