Apache Commons CLI 1.3.1: как игнорировать неизвестные аргументы?

Раньше я работал с 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

Я использовал это решение Паскаля Шефера: Can Анализатор параметров командной строки Apache Commons игнорирует неизвестные параметры командной строки?

У меня это отлично работало на 1.2, а также на 1.3.1. Но это устарело. Парсер, который я использовал, был заменен на DefaultParser. Я посмотрел функционал, но такого метода нет processOptions.

Я действительно хотел бы использовать код, который не будет удален в более поздних выпусках. Кто-нибудь знает, как решить эту проблему?


person leif_good    schedule 23.11.2015    source источник
comment
Заданный вопрос относится к более старой версии плагина, и я даже имею в виду ее, так как это дубликат?   -  person leif_good    schedule 23.11.2015
comment
Я голосую за повторное открытие, потому что вопрос явно требует неустаревшего способа решения проблемы.   -  person Olivier Grégoire    schedule 23.11.2015


Ответы (3)


Спасибо, @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]));
}

}

person aalosious    schedule 20.04.2020

Здесь можно использовать тот же подход, что и в решении Паскаля.

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

Или, альтернативно, удалите неизвестные параметры из аргументов, как указано выше, и используйте метод DefaultParser.

person kjp    schedule 02.06.2018
comment
Это не сработает, если вы хотите использовать аргументы со значениями, так как они будут отфильтрованы. - person Asu; 18.06.2019

Это должно работать для вашего варианта использования:

Options options = new Options();
CommandLine commandLine = new DefaultParser().parse(options, args, true);

Важной частью для вас является stopAtNonOption: true:

Флаг, указывающий, как обрабатываются нераспознанные токены. Значение true, чтобы остановить синтаксический анализ и добавить оставшиеся токены в список аргументов. false, чтобы вызвать исключение.

Документы по адресу https://commons.apache.org/proper/commons-cli/javadocs/api-1.3.1/org/apache/commons/cli/DefaultParser.html#stopAtNonOption

person Olivier Grégoire    schedule 23.11.2015
comment
Извините, может быть, я плохо выразился: метод, который вы мне советуете использовать, не решает проблему, поскольку программа ОСТАНОВИТ разбор аргумента, даже если он не выдает исключение. В моем случае синтаксический анализ должен продолжаться, а неизвестный аргумент следует только игнорировать или пропускать. Собираюсь добавить некоторые детали к вопросу. Простите за это. - person leif_good; 23.11.2015
comment
Лучше отредактировать этот ответ, так как это не решение вопроса, но это может быть другое решение для других людей. - person SexyNerd; 06.05.2017
comment
Я попробовал вышеуказанный вариант, и синтаксический анализ отправляет ParseException (даже когда код говорит, что этого не должно быть). Возможно, есть ошибка в DefaultParser. - person JACH; 07.12.2017
comment
Отклонить мой предыдущий комментарий. False отправляет ParseException при обнаружении неизвестного параметра, что, вероятно, не то, что было задано в этом вопросе. Правда, с другой стороны, игнорирует их (и, если это верно для его имени, он останавливается). Я не уверен, останавливается ли он полностью (игнорируя все после того, как опция не была распознана) или нет. - person JACH; 07.12.2017