我正在编写一个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);
}
这适用于我(其他解析器也可以派生):
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);
}
}
}
使用Commons CLI无法做到这一点。但是,如果您提供有关用例的更多详细信息,可能还有另一种方法可以实现您期望的结果。
我是一个非常糟糕的开发人员,我这样做是为了打破代码:
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();
正如评论中所提到的,接受的解决方案不再合适,因为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保存在单独的列表中。