提问人:Madara's Ghost 提问时间:7/26/2015 更新时间:7/26/2015 访问量:70
如何以与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;
}
答:
2赞
Birei
7/26/2015
#1
您可以尝试使用库,使用以下方法导入:opencsv
gradle
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, שלום עליכם]
评论
0赞
Madara's Ghost
7/26/2015
这实际上看起来很有前途!谢谢!我会看看我是否可以整合这个想法,如果我这样做,我会接受。
评论
\uHEXA
\
u
H
E
X
A
HEXA
main (String ...args)
\uHEXA
"\\uHEXA"