7

在 Java 中解析类似 shell 的命令行的推荐方法是什么。By that I don't mean processing the options when they are already in array form (eg handling "-x" and such), there are loads of questions and answers about that already.

不,我的意思是将完整的命令字符串拆分为“令牌”。我需要转换一个字符串,例如:

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)

4

3 回答 3

0

你需要的是实现一个有限自动机。您需要逐个字符地读取字符串,并根据您的下一个或上一个字符找到下一个状态。
例如,a"表示字符串的开始,但如果它前面有 an,\则保持当前状态不变并读取直到下一个标记带您进入下一个状态。
即基本上在你的例子中你会有

read string -> read number   
      ^  -    -   -  |  

您当然需要定义所有状态以及影响或不影响您的状态的特殊字符。
老实说,我不确定您为什么要向最终用户提供此类功能。
传统上,所有 cli 程序都接受标准格式-x or --x or --x=s等的输入。
这种格式对于典型用户来说是众所周知的,并且易于实现和测试为正确的。
传统上,如果我们需要为用户提供更“灵活”的输入,最好构建一个 GUI。这就是我的建议。

于 2013-05-23T19:42:50.817 回答
0

DrJava 的ArgumentTokenizer以 Bourne shell 及其衍生工具的方式解析命令行

它正确支持转义,因此bash -c 'echo "\"escaped '\''single'\'' quote\""'被标记为[bash, -c, echo "\"escaped 'single' quote\""].

于 2015-02-21T01:15:03.843 回答
-1

将 args[] 重新构建为字符串,然后使用正则表达式进行标记:

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);
}

后半部分我取自这里

于 2013-05-23T19:37:07.270 回答