15

我曾经使用 Apache Commons Cli 1.2。如果参数未知(未添加到选项对象),我希望解析器忽略它们。

示例(伪代码):

Options specialOptions;
specialOptions.addOption(null, "help", false, "shows help");
specialOptions.addOption(null, "version", false, "show version");

CommandLineParser parser = new DefaultParser();
CommandLine cmd = parser.parse(options, args); //no third argument, since i dont want the program to stop parsing.
// run program with args: --help --unknown --version
// program shall parse --help AND --version, but ignore --unknown

我使用了 Pascal Schäfer 的解决方案: Apache Commons CLI 选项解析器可以忽略未知的命令行选项吗?

这对我来说在 1.2 上很好用,在 1.3.1 上也很好用。但它已被弃用。我使用的解析器被替换为DefaultParser. 我查了功能,但没有这样的方法processOptions

我真的很想使用不会在以后的版本中删除的代码。有谁知道如何解决这个问题?

4

3 回答 3

5

谢谢@kjp 的建议;但解决方案不适用于具有值的参数。

我尝试改进 kjp 的解决方案:

public class RelaxedParser extends DefaultParser {

@Override
public CommandLine parse(final Options options, final String[] arguments) throws ParseException {
    final List<String> knownArgs = new ArrayList<>();
    for (int i = 0; i < arguments.length; i++) {
        if (options.hasOption(arguments[i])) {
            knownArgs.add(arguments[i]);
            if (i + 1 < arguments.length && options.getOption(arguments[i]).hasArg()) {
                knownArgs.add(arguments[i + 1]);
            }
        }
    }
    return super.parse(options, knownArgs.toArray(new String[0]));
}

}

于 2020-04-20T21:09:16.003 回答
3

这里可以使用 Pascal 在解决方案中给出的相同方法。

public class RelaxedParser extends DefaultParser {

    @Override
    public CommandLine parse(Options options, String[] arguments) throws ParseException {
        List<String> knownArguments = new ArrayList<>();
        for (String arg : arguments) {
            if (options.hasOption(arg)) {
                knownArguments.add(arg);
            }
        }
        return super.parse(options, knownArguments.toArray(new String[knownArguments.size()]));
    }
}

或者,如上所述从 args 中删除未知选项并使用 DefaultParser。

于 2018-06-02T01:15:17.717 回答
1

这应该适用于您的用例:

Options options = new Options();
CommandLine commandLine = new DefaultParser().parse(options, args, true);

对您来说重要的部分是 stopAtNonOption: true

指示如何处理无法识别的令牌的标志。true 停止解析并将剩余的标记添加到 args 列表中。false 抛出异常。

https://commons.apache.org/proper/commons-cli/javadocs/api-1.3.1/org/apache/commons/cli/DefaultParser.html#stopAtNonOption上的文档

于 2015-11-23T15:54:00.520 回答