Подобный этому потоку для C#, я должен разделить строку, содержащую параметры командной строки к моей программе, таким образом, я могу позволить пользователям легко выполнять несколько команд. Например, у меня могла бы быть следующая строка:
-p /path -d "here's my description" --verbose other args
Учитывая вышеупомянутое, Java обычно передавал бы следующее в основному:
Array[0] = -p
Array[1] = /path
Array[2] = -d
Array[3] = here's my description
Array[4] = --verbose
Array[5] = other
Array[6] = args
Я не должен волноваться ни о каком расширении оболочки, но должно быть достаточно умно обработать одинарные и двойные кавычки и любые Escape, которые могут присутствовать в строке. Кто-либо знает о способе проанализировать строку, как оболочка была бы при этих условиях?
Примечание: Я не должен делать парсинга командной строки, я уже использую joptsimple, чтобы сделать это. Скорее я хочу сделать свою программу легко scriptable. Например, я хочу, чтобы пользователь смог поместить в единственном файле ряд команд что, каждый из которых был бы допустим на командной строке. Например, они могли бы ввести следующее в файл:
--addUser admin --password Admin --roles administrator,editor,reviewer,auditor
--addUser editor --password Editor --roles editor
--addUser reviewer --password Reviewer --roles reviewer
--addUser auditor --password Auditor --roles auditor
Затем пользователь выполнил бы мое административное средство следующим образом:
adminTool --script /path/to/above/file
main()
затем найдет --script
опция и выполняет итерации по различным строкам в файле, разделяя каждую строку на массив, что я затем вел бы ответный огонь в joptsimple экземпляре, который будет затем передан в мой драйвер приложения.
joptsimple идет с Синтаксическим анализатором, который имеет метод синтаксического анализа, но он только поддерживает a String
массив. Точно так же конструкторы GetOpt также требуют a String[]
- следовательно потребность в синтаксическом анализаторе.
Вот довольно простая альтернатива для разделения текстовой строки из файла на вектор аргументов, чтобы вы могли передать ее в свой синтаксический анализатор параметров:
Это решение:
public static void main(String[] args) {
String myArgs[] = Commandline.translateCommandline("-a hello -b world -c \"Hello world\"");
for (String arg:myArgs)
System.out.println(arg);
}
Магический класс Командная строка
является частью муравья . Таким образом, вам нужно либо поместить ant в путь к классам, либо просто взять класс Commandline, поскольку используемый метод является статическим.
Вам следует использовать полнофункциональный современный объектно-ориентированный анализатор аргументов командной строки. Я предлагаю свой любимый Java Simple Argument Parser . И , как использовать JSAP , здесь в качестве примера используется Groovy, но то же самое для обычного Java. Существует также args4j , который в некотором смысле более современен, чем JSAP, потому что он использует аннотации, держитесь подальше от материала apache.commons.cli, он старый и сломанный, очень процедурный и не-Java-eques в свой API. Но я по-прежнему прибегаю к JSAP, потому что так легко создать свои собственные обработчики аргументов.
Существует множество парсеров по умолчанию для URL-адресов, чисел, InetAddress, цвета, даты, файла, класса, и очень легко добавить свои собственные.
Например, вот обработчик для сопоставления аргументов с перечислениями:
import com.martiansoftware.jsap.ParseException;
import com.martiansoftware.jsap.PropertyStringParser;
/*
This is a StringParser implementation that maps a String to an Enum instance using Enum.valueOf()
*/
public class EnumStringParser extends PropertyStringParser
{
public Object parse(final String s) throws ParseException
{
try
{
final Class klass = Class.forName(super.getProperty("klass"));
return Enum.valueOf(klass, s.toUpperCase());
}
catch (ClassNotFoundException e)
{
throw new ParseException(super.getProperty("klass") + " could not be found on the classpath");
}
}
}
и я не поклонник программирования конфигурации через XML, но JSAP имеет действительно хороший способ объявлять параметры и настройки вне вашего кода, поэтому ваш код не он завален сотнями строк настройки, которые загромождают и затемняют реальный функциональный код, см. мою ссылку на , как использовать JSAP для примера, меньше кода, чем в любой из других библиотек, которые я пробовал.
Это направленное решение вашей проблемы, как разъяснено в вашем обновлении , строки в вашем файле «скрипта» по-прежнему являются командными строками. Построчно считайте их из файла и вызовите JSAP.parse (String);
.
Я использую эту технику, чтобы постоянно обеспечивать функциональность «командной строки» для веб-приложений. Одно конкретное использование было в массовой многопользовательской онлайн-игре с интерфейсом Director / Flash, в котором мы включили выполнение «команд» из чата, например, и использовали JSAP на внутренней стороне для их синтаксического анализа и выполнения кода на основе того, что он проанализировал. Очень похоже на то, что вы хотите сделать, за исключением того, что вы читаете «команды» из файла, а не из сокета. Я бы отказался от joptsimple и просто использовал JSAP, вы действительно испортитесь его мощной расширяемостью.