【问题标题】:Apache Commons CLI 1.3.1: How to ignore unknown Arguments?Apache Commons CLI 1.3.1:如何忽略未知参数?
【发布时间】:2016-02-25 18:53:28
【问题描述】:

我曾经使用 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 的解决方案: Can Apache Commons CLI options parser ignore unknown command-line options?

这对我来说在 1.2 上运行良好,在 1.3.1 上也运行良好。但它已被弃用。我使用的解析器被DefaultParser 取代。查了一下功能,没有processOptions这样的方法。

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

【问题讨论】:

  • 问的问题是插件上的旧版本,我什至在引用它,那么这怎么是重复的?
  • 我投票支持重新开放,因为该问题明确要求采用一种不被弃用的方式来解决问题。

标签: java apache-commons apache-commons-cli


【解决方案1】:

感谢@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]));
}

}

【讨论】:

    【解决方案2】:

    这应该适用于您的用例:

    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

    【讨论】:

    • 对不起,也许我表达自己不好:你告诉我使用的方法并不能解决问题,因为程序将停止解析参数,即使他没有抛出异常。对于我的用例,解析必须继续,未知参数只能被忽略或跳过。将在问题中添加一些细节。很抱歉。
    • 最好编辑这个答案,因为它不是问题的解决方案,但它可能是其他人的另一种解决方案。
    • 我尝试了上述选项并解析发送 ParseException(即使代码说不应该)。可能 DefaultParser 中存在错误。
    • 忽略我之前的评论。当找到未知选项时,False 会发送 ParseException,这可能不是这个问题中所要求的。另一方面,True 忽略它们(并且,如果它的名字是真实的,它就会停止)。我不确定它是否完全停止(在无法识别选项后忽略所有内容)。
    • 我给了这个答案一个赞成票。 Stackoverflow 不会让我删除该投票。我将这个布尔值理解为“忽略未知选项”。相反,如果遇到未知选项,它将停止解析。我有一个针对特定环境的参数。这周我运行了一个负载测试,我添加了另一个命令行参数来增加流量。令我惊讶的是,我最终以默认环境为目标并将其删除。叹。至少现在我知道为什么了。
    【解决方案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。

    【讨论】:

    • 如果你想使用带值的参数,这将不起作用,因为它们会被过滤掉。
    猜你喜欢
    • 1970-01-01
    • 2011-08-28
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 2012-01-25
    • 2013-03-08
    相关资源
    最近更新 更多