【问题标题】:Regex to parse command line options正则表达式解析命令行选项
【发布时间】:2018-11-08 11:46:08
【问题描述】:

我需要将字符串解析为键值对,其中的值可能是可选的。标准命令行解析器没有用,因为我检查的所有解析器都接受String[] 而不是String。因此,我求助于正则表达式,果然,面临以下问题:

有些人在遇到问题时会想“我知道,我会用 正则表达式。”现在他们有两个问题。

一、输入字符串:

"/opt/sensu/embedded/bin/ruby /opt/sensu/embedded/bin/check-graphite-stats.rb " +
"--crit 25 --host 99.99.999.9999:8082 --period -5mins --target 'alias(scale(divideSeries(" +
"summarize(sumSeries(nonNegativeDerivative(transformNull(exclude(" +
"\\\"unknown\\\"), 0))), \\\"30d\\\", \\\"sum\\\", false),summarize(" +
...gigantuous string
\\\"sum\\\", false)), 100), \\\"3pp error rate\\\")' " +
"--unknown-ignore --warn 5"

接下来,我的正则表达式:

(--(?<option>.+?)\s+(?<value>.+?(?=--))?)+?

上述几乎有效,但不完全。

输出:

--crit 25 
--host 99.99.999.9999:8082 
--period -5mins 
--target 'gigantuous string' 
--unknown-ignore 
--warn 

为什么--warn的值没有被拾取?

【问题讨论】:

  • 为什么不将每个参数分别传递给args[]
  • 你的输入是一个shell命令。您是如何最终尝试用 Java 编写 shell 解析器的?
  • 我只有字符串。

标签: java regex command-line command-line-arguments


【解决方案1】:

因为您在正则表达式 ((?=--)) 的末尾对下一个 -- 进行正向前瞻,所以不会拾取字符串中最后一个参数的值,因为它后面没有 @987654323 @。接受字符串的结尾作为替代 ((?:(?=--)|$)),然后过滤不以 -- 开头的值(通过将 .+? 替换为 .(?:[^-].+?)?)应该按照您想要的方式运行:

(--(?<option>.+?)\s+(?<value>.(?:[^-].+?)?(?:(?=--)|$))?)+?

(但是,正如其他人所提到的,我会很惊讶没有适合您的用例的 Java 参数解析库。即使这意味着自己编写代码将字符串拆分为参数,它可能不那么脆弱。)

【讨论】:

  • 不!它会同时接收--unknown-ignore --warn 5
  • 哦,是的,确实如此。在value 组的开头添加[^-] 怎么样? ((--(?&lt;option&gt;.+?)\s+(?&lt;value&gt;[^-].+?((?=--)|$))?)+?)
  • 没有。感谢您的宝贵时间,但是网上有很多正则表达式测试人员,您应该先检查一下;这看起来像是把意大利面扔到墙上希望它会粘住。
  • 啊,抱歉,看来我的测试仪配置错误。 (--(?&lt;option&gt;.+?)\s+(?&lt;value&gt;.([^-].+?)?((?=--)|$))?)+? 应该可以工作。
  • 有些组不是必需的,我将它们转换为非捕获(--(?&lt;option&gt;.+?)\s+(?&lt;value&gt;.(?:[^-].+?)?(?:(?=--)|$))?)+?。除此之外,您的答案对我有用,所以我接受了。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-22
  • 2012-07-08
  • 1970-01-01
  • 2012-06-21
相关资源
最近更新 更多