All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.azbh111.utils.java.command.CommandLine Maven / Gradle / Ivy

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,
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy