21

我正在编写一个 Java 应用程序,它采用带有 GnuParser 的 Apache Commons CLI 处理的命令行参数。由于不感兴趣的原因,我希望它默默地忽略未知的命令行选项,而不是抛出 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);
}
4

4 回答 4

29

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

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

}
于 2011-12-23T08:53:11.287 回答
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()]));
    }

}

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

于 2018-11-14T08:44:51.577 回答
1

这对于 Commons CLI 是不可能的。但是,如果您提供更多用例的详细信息,可能还有另一种方法可以达到您期望的结果。

于 2011-07-18T08:54:11.277 回答
0

我是一个非常糟糕的开发人员,我这样做是为了破坏代码:

public class EasyPosixParser extends PosixParser {
    @Override
    protected void processOption(String arg, ListIterator iter) throws ParseException
    {
        try {
            super.processOption(arg, iter);
        } catch (ParseException e) {
            // do nothing
        }
    }
}

在您的主代码中,您执行以下操作:

    CommandLineParser commandlineParser = new EasyPosixParser();
于 2011-11-11T06:52:19.390 回答