我面临着将字符串解析为键值对的需求,其中值可能是可选的。标准命令行解析器没有用,因为我检查的所有命令行解析器都接受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
的值没有被提取?
答案 0 :(得分:1)
因为您正对正则表达式(--
)末尾的下一个(?=--)
进行正向查找,所以未选择字符串中最后一个参数的值,因为它不是然后是--
。接受字符串的结尾作为替代((?:(?=--)|$)
),然后过滤不以--
开头的值(通过将.+?
替换为.(?:[^-].+?)?
)应在您想要的方式:
(--(?<option>.+?)\s+(?<value>.(?:[^-].+?)?(?:(?=--)|$))?)+?
(但是,正如其他人提到的那样,我很惊讶没有一个适合您使用情况的Java参数解析库。即使这意味着编写代码将自己将字符串拆分为参数,它也会可能不那么脆。)