在Java中解析复杂的标志

问题描述 投票:1回答:2

我正在使用Java将特定标志解析到我的CLI中。该标志是“流”标志,由--stN=表示,其中N表示从1到10000的数字。

=之后的参数是逗号分隔的,并且表示不同的东西 - 通常是关于如何在程序中运行某个操作的命令,用于运行Nth。

这些命令本身可以有0..N个参数。

的;

它们可以混合使用字符串,数字等。

这是我提出的解决方案:

首先,我添加了一个名为--st1=command1,arg1,arg2,command2,arg2,3,command3,command4,5的接口来保存已解析的数据:

StreamOption

接下来,我创建了一个public interface StreamOption { } 来处理流的一部分:

StreamOptionParser

在这个实现中,我将提交流(作为列表,用逗号分隔)。

e.g

public interface StreamOptionParser<T extends StreamOption> {
    StreamReturn parse(List<String> stream, int id) throws ParameterException;
}

结果类型public class CommandOneParser implements StreamOptionParser<CommandOneOption> { StreamReturn parse(List<String> stream, int id) throws ParameterException{ //loop through the list, if terms are found, parse to a StreamObject //if not, pass to the return list of strings.. } } 是一个简单的POJO,允许返回解析的StreamReturn以及需要传递给下一个解析器的任何剩余项。我还需要返回剩余的条款,以检查所有输入是否有效,并且没有任何输入。

StreamOption

它必须持有//bit of lombok @Getter @Setter @AllArgsConstructor public class StreamReturn<T extends StreamOption> { private List<String> remainingOptions; private Optional<List<T>> options = Optional.empty(); } ,因为可以在同一个stream中指定多个命令.List

这是一个好方法吗?或者是否有一个更好的解决方案,更少锅炉?这有什么潜在的问题吗?我认为它可以保持可扩展性,随着程序的增长,我可以在以后轻松添加新的--stN=command1,2,3,command1,4,5,...Options

我似乎无法找到任何开箱即用的解析库/模式,有没有我可能错过的?我正在使用Parsers作为简单的标志,但这对于jcommander来说似乎太复杂了。

先谢谢你,山姆

java parsing command-line-interface
2个回答
0
投票

因此,答案是通过拆分字符串将其视为普通的CLI参数。然后我利用JCommander完成所有耗时的操作,将正确的命令推入正确的转换器。

JCommander

command1,2,3,command2,3,string1,command3command12,3command23,string1

有了这个,我利用JCommander注释将正确的args传递给正确的命令。

command3

和选项:

CommandOneValues{

  int myValue1;
  int myValue2;

}

使用简单的转换器:

@Getter
public class CommandOneOptions {


    @Parameter(names = {"command1"},
        converter = CommandOneConverter.class
    )
    CommandOneValues values;
}

希望这有助于未来的人!


0
投票

除了自定义类型转换器之外,其他工具可能具有可为替代解决方案提供想法的功能。例如,picocli有一些复杂选项的机制可能很有趣:

  • 支持class CommandOneConverter implements IStringConverter<CommandOneValues>{ public CommandOneValues convert(String value){ //conversion... } }
  • quoted options(测试中)

引用选项

假设您按如下方式定义了该选项:

argument groups

默认情况下,picocli的@Option(names = "--st", split = ",") List<String> parts; 函数会在引号内部忽略split,因此您可以使用引号对参数进行分组。用户输入示例:

split regex

Picocli会将值分成以下部分:

--st1="command1,arg1,arg2","command2,arg2,3","command3","command4,5"

以上是拆分的默认行为,不需要自定义转换器或任何其他自定义代码。

论证组

Picocli 4.0将支持重复参数组(仍处于测试阶段),这可能是建模问题的不同方式。如果应用程序的概要看起来像这样对最终用户不是很好吗?

"command1,arg1,arg2"
"command2,arg2,3"
"command3"
"command4,5"

也就是说,myapp (--cmd=<commandName> [<commandArg>...])... 选项与零个或多个位置参数一起成为参数组,并且可以指定该参数组一次或多次。最终用户可以输入如下值:

--cmd

完成此任务的代码可能如下所示:

myapp --cmd=command1 arg1 arg2 --cmd=command2 arg2 3 --cmd=command3 --cmd=command4 5
© www.soinside.com 2019 - 2024. All rights reserved.