将字符串转换为 shell 参数

Ion*_*zău 6 javascript regex bash shell node.js

我感兴趣的是如何将 bash 输入解析为参数。

例如,通过使用process.argv我们可以在 NodeJS 中获取字符串数组(但这与语言无关)。

我的问题是如何将输入解析"node foo.js --foo "bar baz" -b foo"为数组process.argv(或其他语言中的等效项)返回(例如["node", "foo.js", "--foo", "\"bar baz\"", "-b", "foo"]

按空格分割是不够的(因为引号)。是否可以使用一些更复杂的正则表达式来处理引号并获取这样的数组?

Jam*_*mas 5

使用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' ]
Run Code Online (Sandbox Code Playgroud)


Uni*_*ron 5

由于正则表达式解决方案似乎是明确要求的,而这是适当解析器的任务类型,因此这里有一个令人兴奋的正则表达式单行代码。

考虑规格:

  • JS兼容
  • 按空格标记但保留"..."'...'在一起

可以使用一个简单的match函数来查找值,但缺点是无法很好地检测嵌套的引号转义(正则表达式的递归匹配很困难。)

>>> str = "node foo.js --foo \"bar baz\" -b foo";
    str.match(/"[^"]+"|'[^']+'|\S+/g)
<<< ["node", "foo.js", "--foo", "\"bar baz\"", "-b", "foo"]
Run Code Online (Sandbox Code Playgroud)

(简化)正则表达式解释:

  • "[^"]+"|'[^']+'是一个子模式,用于查找引号对,其间除了引号本身之外还有任何内容。
  • |替代另一个选项。
  • \S是 的否定\s:它匹配非空白序列,这有效地断言我们匹配之前未收集的标记。量化+整个字符串。