我正在制作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");
}
}
}
答案 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
。