将string转换为shell参数
我感兴趣的是如何parsingbashinput到参数。
例如,通过使用process.argv
我们在NodeJS中获得了一个string数组(但是这是语言不可知的)。
我的问题是如何parsing像"node foo.js --foo "bar baz" -b foo"
input到类似于process.argv
(或其他语言的等价物)返回(例如["node", "foo.js", "--foo", "\"bar baz\"", "-b", "foo"]
?
由空间分割是不够的(由于报价)。 是否有可能用一些更复杂的正则expression式来处理引号并得到这样一个数组?
由于一个正则expression式的解决scheme似乎被明确要求,而这是一个适当的parsing器的任务,这里是一个正则expression式的惊险刺激。
考虑到规格:
- JS-兼容
- 用空格标记,但保留
"..."
或'...'
一个简单的match
函数可以用来查找值,不利的是嵌套转义报价将不能很好地检测(regexesrecursion匹配已经很困难。)
>>> str = "node foo.js --foo \"bar baz\" -b foo"; str.match(/"[^"]+"|'[^']+'|\S+/g) <<< ["node", "foo.js", "--foo", "\"bar baz\"", "-b", "foo"]
(简体)正则expression式解释:
-
"[^"]+"|'[^']+'
是一个子模式,用于查找除引号之外的任何引号。 -
|
替代另一个选项。 -
\S
是\s
的否定:它匹配非空白序列,这有效地断言我们匹配先前未收集的记号。+
量化整个string。
使用shell-quote NPM包将会处理这个问题。
var parse = require('shell-quote').parse; parse('node foo.js --foo "bar baz" -b foo'); [ 'node', 'foo.js', '--foo', 'bar baz', '-b', 'foo' ]