com.github.azbh111.utils.java.command.CommandLine Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of utils-java Show documentation
Show all versions of utils-java Show documentation
com.github.azbh111:utils-java
The newest version!
package com.github.azbh111.utils.java.command;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author: zyp
* @date: 2020/6/6 12:13 下午
*/
public class CommandLine {
/**
* 固定参数
*/
private String[] args;
/**
* 具名参数
*/
private Map> kwargs;
/**
* 解析命令行
*
* @param prefix 参数前缀
* @param quote 字符串标识,一般是双引号或者单引号
* @param line 命令行
* @return
*/
public static CommandLine of(String prefix, char quote, String line) {
if (line == null) {
return null;
}
CommandLine cl = new CommandLine();
if (line.isEmpty()) {
return cl;
}
String[] parts = split(quote, '\\', line);
List args = new ArrayList<>();
Map> kwargs = new HashMap<>();
for (int i = 0; i < parts.length; i++) {
String part = parts[i];
if (part.startsWith(prefix) && part.length() > prefix.length()) {
String name = part.substring(prefix.length());
String v = i + 1 < parts.length ? parts[i + 1] : "";
kwargs.computeIfAbsent(name, k -> new ArrayList<>())
.add(v);
i++;
} else {
args.add(part);
}
}
cl.args = args.toArray(new String[args.size()]);
cl.kwargs = kwargs;
return cl;
}
/**
* 对命令进行拆分
*
* @param quote 字符串标识,一般是双引号或者单引号
* @param line
* @return
*/
public static String[] split(char quote, char escape, String line) {
if (line == null) {
return null;
}
if (line.isEmpty()) {
return new String[0];
}
List parts = new ArrayList<>();
StringBuilder part = null;
Status status = Status.whitespace;
int idx = -1;
while (true) {
idx++;
if (idx >= line.length()) {
if (status == Status.quote) {
// 引号没结束
throw new RuntimeException("未结束的引号: " + line);
}
if (part != null) {
parts.add(part.toString());
}
part = null;
break;
}
char c = line.charAt(idx);
if (status == Status.whitespace) {
if (Character.isWhitespace(c)) {
// 空格
continue;
}
part = new StringBuilder();
if (c == escape) {
status = Status.normal;
idx++;
c = line.charAt(idx);
part.append(c);
} else if (c == quote) {
status = Status.quote;
continue;
} else {
status = Status.normal;
part.append(c);
}
} else if (status == Status.normal) {
if (Character.isWhitespace(c)) {
status = Status.whitespace;
parts.add(part.toString());
part = null;
continue;
} else if (c == escape) {
idx++;
c = line.charAt(idx);
part.append(c);
} else {
part.append(c);
}
} else if (status == Status.quote) {
if (c == escape) {
idx++;
c = line.charAt(idx);
part.append(c);
} else if (c == quote) {
status = Status.whitespace;
parts.add(part.toString());
part = null;
continue;
} else {
part.append(c);
}
}
}
return parts.toArray(new String[parts.size()]);
}
public String[] getArgs() {
return args;
}
public Map> getKwargs() {
return kwargs;
}
private static enum Status {
normal,
whitespace,
// 有引号的字符串
quote,
}
}