Apache Commons CLI选项解析器可以忽略未知的命令行选项吗?

Mic*_*ley 20 java apache-commons apache-commons-cli

我正在编写一个Java应用程序,它接受使用Apache Commons CLI和GnuParser处理的命令行参数.由于没有兴趣进入的原因,我希望它默默地忽略未知的命令行选项而不是抛出ParseException,但我没有看到这样做的方法.我看到GnuParser.parse()上有一个stopAtNonOption布尔选项,但我想要的更像ignoreAtNonOption,它会在遇到未知令牌后继续处理选项.

我可以实现我自己的解析器来完成这个,但我很惊讶没有内置这个功能,所以我想我会在走这条路之前检查一下.

我正在谈论的示例代码:

try {
  CommandLine commandLine = parser.parse(options, args);
  // stopAtNonOption set to true (below) is also not what I want
  // CommandLine commandLine = parser.parse(options, args, true);
} catch (ParseException e) {
  LOG.error("error parsing arguments", e);
  throw new RuntimeException(e);
}
Run Code Online (Sandbox Code Playgroud)

小智 28

这适用于我(其他解析器也可以派生):

public class ExtendedGnuParser extends GnuParser {

    private boolean ignoreUnrecognizedOption;

    public ExtendedGnuParser(final boolean ignoreUnrecognizedOption) {
        this.ignoreUnrecognizedOption = ignoreUnrecognizedOption;
    }

    @Override
    protected void processOption(final String arg, final ListIterator iter) throws     ParseException {
        boolean hasOption = getOptions().hasOption(arg);

        if (hasOption || !ignoreUnrecognizedOption) {
            super.processOption(arg, iter);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 那太好了,谢谢!顺便说一句,这应该是任何API设计师的一个注释,为什么你绝对不想让你的API类最终.为什么?因为你不够聪明,无法弄清楚客户端代码想要重用你的东西的所有方式. (8认同)

Sim*_*oV8 7

如评论中所述,已接受的解决方案不再适合,因为该processOption方法已被弃用并已删除。

这是我的解决方案:

public class ExtendedParser extends DefaultParser {

    private final ArrayList<String> notParsedArgs = new ArrayList<>();

    public String[] getNotParsedArgs() {
        return notParsedArgs.toArray(new String[notParsedArgs.size()]);
    }

    @Override
    public CommandLine parse(Options options, String[] arguments, boolean stopAtNonOption) throws ParseException {
        if(stopAtNonOption) {
            return parse(options, arguments);
        }
        List<String> knownArguments = new ArrayList<>();
        notParsedArgs.clear();
        boolean nextArgument = false;
        for (String arg : arguments) {
            if (options.hasOption(arg) || nextArgument) {
                knownArguments.add(arg);
            } else {
                notParsedArgs.add(arg);
            }

        nextArgument = options.hasOption(arg) && options.getOption(arg).hasArg();
        }
        return super.parse(options, knownArguments.toArray(new String[knownArguments.size()]));
    }

}
Run Code Online (Sandbox Code Playgroud)

与 Pascal 提出的解决方案相比,它还检查带有参数的选项,并将未解析的 args 保留在单独的列表中。