是否有Java的shlex替代品?我希望能够分割用引号分隔的字符串,就像shell会处理它们一样。例如,如果我发送:一二“三四”并执行分割,我想接收 token onetwo三四十四

最佳答案

我今天遇到了类似的问题,看起来像StringTokenizer,StrTokenizer,Scanner这样的标准选项都不适合。但是,实现基础并不难。

此示例处理当前在其他答案上已评论的所有极端情况。请注意,我尚未检查它是否完全符合POSIX。要点包括可用的单元测试on GitHub-通过无许可证在公共(public) Realm 发布。

public List<String> shellSplit(CharSequence string) {
    List<String> tokens = new ArrayList<String>();
    boolean escaping = false;
    char quoteChar = ' ';
    boolean quoting = false;
    int lastCloseQuoteIndex = Integer.MIN_VALUE;
    StringBuilder current = new StringBuilder();
    for (int i = 0; i<string.length(); i++) {
        char c = string.charAt(i);
        if (escaping) {
            current.append(c);
            escaping = false;
        } else if (c == '\\' && !(quoting && quoteChar == '\'')) {
            escaping = true;
        } else if (quoting && c == quoteChar) {
            quoting = false;
            lastCloseQuoteIndex = i;
        } else if (!quoting && (c == '\'' || c == '"')) {
            quoting = true;
            quoteChar = c;
        } else if (!quoting && Character.isWhitespace(c)) {
            if (current.length() > 0 || lastCloseQuoteIndex == (i - 1)) {
                tokens.add(current.toString());
                current = new StringBuilder();
            }
        } else {
            current.append(c);
        }
    }
    if (current.length() > 0 || lastCloseQuoteIndex == (string.length() - 1)) {
        tokens.add(current.toString());
    }

    return tokens;
}

08-16 18:18