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

发布于 2024-11-07 22:33:31 字数 646 浏览 0 评论 0原文

我正在编写一个 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);
}

I am writing a Java application that takes command line arguments which are processed using Apache Commons CLI with the GnuParser. For reasons that are not interesting to get into, I would like it to silently ignore unknown command line options instead of throwing a ParseException but I don't see a way to do that. I see that there is a stopAtNonOption boolean option on GnuParser.parse() but what I want is more like ignoreAtNonOption where it will keep processing options after encountering an unknown token.

I could implement my own parser to accomplish this but I'm surprised there isn't this functionality built in so I thought I'd check before going down that road.

Example code for what I'm talking about:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

黄昏下泛黄的笔记 2024-11-14 22:33:32

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

This is not possible with Commons CLI. But there may be another way to achieve the result you expect if you give more details of your use case.

吃不饱 2024-11-14 22:33:32

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

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

I am a very bad developer, and I do this to break the code:

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

in your main code, you do:

    CommandLineParser commandlineParser = new EasyPosixParser();
橘虞初梦 2024-11-14 22:33:31

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

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

}

This works for me (other parsers can be derived, too):

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

}
一影成城 2024-11-14 22:33:31

正如评论中提到的,已接受的解决方案不再合适,因为 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 提出的解决方案相比,它还检查带参数的选项,并将未解析的参数保留在单独的列表中。

As mentioned in a comment, the accepted solution is no more suitable because the processOption method has been deprecated and removed.

Here's my solution:

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

}

Compared with the solution proposed by Pascal, it also checks for options with arguments and it keeps not parsed args in a separate list.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文