在Java中解析类似shell的命令行的推荐方法是什么。我并不是说当它们已经是数组形式时处理选项(例如处理“-x”等),已经有很多问题和答案。
不,我的意思是将完整的命令字符串拆分为“令牌”。我需要转换一个字符串,如:
user 123712378 suspend "They are \"bad guys\"" Or\ are\ they?
...到列表/数组:
user
123712378
suspend
They are "bad guys"
Or are they?
我目前正在对空格进行拆分,但显然无法处理引号和转义空格。
(引用处理是最重要的。转义空间会很好用)
注意:我的命令字符串是来自类似shell的Web界面的输入。它不是由main(String[] args)
答案 0 :(得分:0)
您需要的是实现有限自动机。您需要逐个字符地读取字符串,并根据您的下一个或上一个字符找到下一个状态
例如,"
表示字符串的开头,但如果前面有\
则保持当前状态不变,并读取直到下一个将您带到下一个状态的标记。
即基本上在你的例子中你会有
read string -> read number
^ - - - |
您当然需要定义影响或不影响您所在州的所有州和特殊字符
说实话,我不确定你为什么要为最终用户提供这样的功能
传统上,所有cli程序都接受标准格式-x or --x or --x=s
等的输入
这种格式对于普通用户来说是众所周知的,并且易于实现和测试正确
传统上,如果我们需要为用户提供更多“灵活”的输入,最好构建一个GUI。这就是我的建议。
答案 1 :(得分:0)
ArgumentTokenizer以Bourne shell及其派生词的方式解析命令行。
它正确支持转义,因此bash -c 'echo "\"escaped '\''single'\'' quote\""'
被标记为[bash, -c, echo "\"escaped 'single' quote\""]
。
答案 2 :(得分:-1)
将args []重新构建成一个字符串,然后使用regexp:
进行标记public static void main(String[] args) {
String commandline = "";
for(String arg : args) {
commandline += arg;
commandline += " ";
}
System.out.println(commandline);
List<String> list = new ArrayList<String>();
Matcher m = Pattern.compile("([^\"]\\S*|\".+?\")\\s*").matcher(commandline);
while (m.find())
list.add(m.group(1)); // Add .replace("\"", "") to remove surrounding quotes.
System.out.println(list);
}
后一部分我从here开始。