簡體   English   中英

如何以bash相同的方式解析命令行序列?

[英]How to parse a sequence of commands line in the same way bash would?

輸入

我有以下示例輸入(每個輸入都是bash可執行命令):

client-properties create mode "publisher" "version" "mode"
client-properties set "publisher" "version" "mode" "prop1" "value
value
value"
client-properties set "publisher" "version" "mo\"de" "prop2" "שלום עליכם"

產量

由此,我想將其解析為3個String[] ,如下所示:

{"client-properties", "create", "mode", "publisher", "version", "mode"}
{"client-properties", "set", "publisher", "version", "mode", "prop1", "value\nvalue\nvalue"}
{"client-properties", "set", "publisher", "version", "mo\"de", "prop2", "שלום עליכם"}
//                                                   (mo"de)

要求

硬性要求如下:

  • 換行符表示新的聲明。
  • 空格表示單個參數。
  • 用雙引號( " )分隔的參數被視為單個參數,即使它具有空格或換行符
  • 可以使用\\"轉義序列在參數中插入文字雙引號
  • 允許使用Unicode字符(假設UTF8是安全的)。

我嘗試過的

我研究了正則表達式,但是它變得非常復雜,非常快。 我研究了StringTokenizer (看起來很原始)和StreamTokenizer (其中Unicode處理得不太好)。

如果可能,我想避免手動編寫解析器。

有什么想法嗎? 我的最新嘗試如下:

public static List<String> tokenize(String s) {
    List<String> opts = new ArrayList<>();
    try (StringReader sr = new StringReader(s)) {
        StreamTokenizer st = new StreamTokenizer(sr);
        st.resetSyntax();
        // From      ! to end of ascii range. But alas, no unicode
        st.wordChars(31, 127);
        st.quoteChar('\"');
        st.whitespaceChars(32, 32);
        while (st.nextToken() != StreamTokenizer.TT_EOF) {
            opts.add(st.sval);
        }
    } catch (IOException e) {}

    return opts;
}

您可以嘗試使用使用gradle導入的opencsv庫,例如:

compile 'net.sf.opencsv:opencsv:3.4'

嘗試類似於以下程序的操作:

import com.opencsv.CSVReader;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {

    private static final char SEPARATOR = ' ';
    private static final char QUOTE_CHAR = '"';
    private static final char ESCAPE = '\\';

    public static void main(String[] args) throws IOException {
        List<String[]> result = new ArrayList<>();

        CSVReader reader = new CSVReader(
                new FileReader(args[0]),
                SEPARATOR,
                QUOTE_CHAR,
                ESCAPE);

        result.addAll(reader.readAll());

        for (int i = 0; i < result.size(); i++) {
            System.out.println(Arrays.toString(result.get(i)));
        }

    }

}

產生:

[client-properties, create, mode, publisher, version, mode]
[client-properties, set, publisher, version, mode, prop1, value
value
value]
[client-properties, set, publisher, version, mo"de, prop2, שלום עליכם]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM