将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' ]