我想获取参数数组,以便我可以将它与 optparse-js library 一起使用所以如果我有类似的东西
-f foo -b -a -z baz bar
我想要这样的数组
["-f", "foo", "-b", "-a", "-z", "baz", "bar"]
它应该可以处理内部有转义引号和长 GNU 选项的字符串。到目前为止,我有匹配字符串的正则表达式
/("(?:\\"|[^"])*"|'(?:\\'|[^'])*')/g
它匹配像 "das"
或 "asd\"asd"
或 'asd'
或 'sad\' 这样的字符串asd'
我可以为此使用正则表达式还是我需要一个解析器(比如使用 PEG),如果它与正则表达式匹配就更好了,这样我就可以做
-p "hello b\"ar baz" -f /^ [^ ]+ $/
更新:在@Damask 的帮助下,我创建了这个正则表达式:
/('(\\'|[^'])*'|"(\\"|[^"])*"|\/(\\\/|[^\/])*\/|(\\ |[^ ])+|[\w-]+)/g
它适用于这样的字符串:
echo -p "hello b\"ar baz" -f /^ [^ ]+ $/
返回
['echo', '-p', '"hello b\"ar baz"', '-f', '/^ [^ ]+ $/']
但是如果在这样的字符串上失败:
echo "©\\\\" abc "baz"
它匹配命令和两个参数而不是 3 个参数 demo
如果参数没有像 "foo"baz 这样的空格,它应该是数组中的一项,需要包含引号,但我会从字符串中删除未转义的(就像在 bash 中执行 echo "foo "bar
echo 将得到一个 foobar 参数。
最佳答案
一些评论:
引号的原始正则表达式是这样的
"[^"\\]*(?:\\[\S\s][^"\\]*)*"|'[^'\\]*(?:\\[\S\s][^'\\]*)*'
示例:http://regex101.com/r/uxqApc/2这部分
(?= :? | $ )
将始终解析为 true,并且没有用这部分
/(\\/|[^/])+/[gimy]*
如果这是一个正则表达式(或任何分隔项)
你必须盲目地处理逃避任何事情。像这样/[^/\\]*(?:\\[\S\s][^/\\]*)*/[gimy]*
。
否则它会匹配/..\\//
这是不正确的。这个表达式
(?:\\\s |\S )+
在交替序列中是第一个,即在这个[\w-]+
。由于非空白\S
是[\w-]
的超集,这意味着此[\w-]+
永远不会达到.
进行更正并将其全部放回原处得到此正则表达式:
/("[^"\\]*(?:\\[\S\s][^"\\]*)*"|'[^'\\]*(?:\\[\S\s][^'\\]*)*'|\/[^\/\\]*(?:\\[\S\s][^\/\\]*)*\/[gimy ]*(?=\s|$)|(?:\\\s|\S)+)/
演示:
JavaScript - http://regex101.com/r/cuJuQ8/1
PCRE - http://regex101.com/r/cuJuQ8/2
( # (1 start)
"
[^"\\]*
(?: \\ [\S\s] [^"\\]* )*
"
|
'
[^'\\]*
(?: \\ [\S\s] [^'\\]* )*
'
|
/
[^/\\]*
(?: \\ [\S\s] [^/\\]* )*
/
[gimy]*
(?= \s | $ )
|
(?: \\ \s | \S )+
) # (1 end)
如果您还需要将其解析为空格(引号或正则表达式之外)也是定界符,就这样:
/((?:"[^"\\]*(?:\\[\S\s][^"\\]*)*"|'[^'\\]*( ?:\\[\S\s][^'\\]*)*'|\/[^\/\\]*(?:\\[\S\s][^\/\\]* )*\/[gimy]*(?=\s|$)|(?:\\\s|\S))+)(?=\s|$)/
演示:
JavaScript - http://regex101.com/r/cuJuQ8/3
PCRE - https://regex101.com/r/cuJuQ8/4
格式化
( # (1 start)
(?:
"
[^"\\]*
(?: \\ [\S\s] [^"\\]* )*
"
|
'
[^'\\]*
(?: \\ [\S\s] [^'\\]* )*
'
|
/
[^/\\]*
(?: \\ [\S\s] [^/\\]* )*
/
[gimy]*
(?= \s | $ )
|
(?: \\ \s | \S )
)+
) # (1 end)
(?= \s | $ )
关于javascript - 如何在javascript中将字符串拆分为参数和选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13796594/