使用双引号组合参数

时间:2017-07-07 12:21:14

标签: java

我正在制作TeamSpeak3 ServerQuery bot,命令行样式。我已经把命令放下了,但我似乎无法理解的是命令的参数。我使用reset()方法创建一个参数列表,这样组合字符串会更容易。

例如,假设我在内存中更改了我的机器人名称

set query name "Kyles Bot"

但该程序将“Kyles和Bot”视为两个不同的论点。我希望他们成为一体。我该怎么做呢?

reset()所需的字段:

// Keep String[] and 3 strings null for now, they'll be changed.
private String command, to1, to2;
private String[] to3;
private List<String> args = new ArrayList<>();

reset()方法:

private void reset() {
            args.clear();
            to1 = line.getText();
            command = to1.split(" ")[0];
            if (to1.split(" ").length > 1) {
                to2 = to1.substring(command.length() + 1, to1.length());
                to3 = to2.split(" ");
                for (int i = 0; i < to3.length; i++) {
                    if (to3[i].isEmpty() || to3[i].startsWith(" ")) {
                        System.out.println("Argument null, command cancelled. [" + to3[i] + "]");
                        break;
                    } else {
                        args.add(to3[i]);
                    }
                }
                //EDIT2: Removed useless for loop, 
                //it was my previous attempt to solve the problem.
            } else {
                //EDIT: This loop here is used to prevent AIOUB
                command = to1;
                for (int i = 0; i < 5; i++) {
                    args.add("NullElement");
                }
            }
        }

1 个答案:

答案 0 :(得分:1)

问题在于这一行:

to3 = to2.split(" ");

它在每个空格上拆分读取命令,包括引用文本内的空格。

您需要正确拆分命令行,例如使用正则表达式:

    // matches either a "quoted string" or a single word, both followed by any amount of whitespace
    Pattern argumentPattern = Pattern.compile("(\"([^\"]|\\\")*\"|\\S+)\\s*");

    // loop over all arguments
    Matcher m = argumentPattern.matcher(to2);
    for (int start = 0; m.find(start); start = m.end()) {

        // get a single argument and remove whitespace around it
        String argument = m.group(1).trim();

        // handle quoted arguments - remove outer quotes and unescape inner ones
        if (argument.startsWith("\""))
            argument = argument.substring(1,  argument.length() - 1).replace("\\\"", "\"");

        // ... your code that uses the argument here

    }

请注意,这不是命令行解析器的完整实现 - 如果您收到任意命令,您应该查看为您执行此解析的库,并且可以正确处理所有细节。

PS:请使用描述性变量名而不是to1, to2, to3等,例如我在代码中使用argument代替to3