英文:
How to get os.Args-like tokens from a command line string
问题
我有一个字符串变量:
commandLineString := `echo -n "a b c d"`
我想将其转换为:
args := []string{"echo", "-n", "\"a b c d\""}
我该如何做到这一点?
英文:
I have a string variable:
commandLineString := `echo -n "a b c d"`
I want to covert it to:
args := []string{"echo", "-n", "\"a b c d\""}
How can I do it?
答案1
得分: 1
这可以用正则表达式以非常简洁的方式表示。
输入(命令)是一系列的标记,它们可以是:
- 非引号标记,不能包含引号和空格,
- 或者被引号包围的标记,直到下一个引号标记,可以包含空格(但不能包含引号)。
并且:
- 标记之间用空格或输入结束符分隔。
满足上述条件的正则表达式为:
("[^"]*"|[^"\s]+)(\s+|$)
条件: __2____ __1___ __3__
使用Go的regexp
包,解决方案非常简短:
s := `echo -n "a b c d"`
pattern := `("([^"]*)"|[^"\s]+)(\s+|$)`
r := regexp.MustCompile(pattern)
fmt.Printf("%q\n", r.FindAllStringSubmatch(s, -1))
fmt.Printf("%q\n", r.FindAllString(s, -1))
输出结果(在Go Playground上尝试):
[["echo " "echo" " "] ["-n " "-n" " "] ["\"a b c d\"" "\"a b c d\"" ""]]
["echo " "-n " "\"a b c d\""]
请注意,regexp.FindAllString()
的结果还包含标记之间的分隔符(空格),因此您可以调用strings.TrimSpace()
来删除它们:
ss := r.FindAllString(s, -1)
out1 := make([]string, len(ss))
for i, v := range ss {
out1[i] = strings.TrimSpace(v)
}
fmt.Printf("%q\n", out1)
这将得到所需的输出:
["echo" "-n" "\"a b c d\""]
或者您可以使用regexp.FindAllStringSubmatch()
的结果:它返回一个切片的切片,使用每个元素的第二个元素(索引为1
):
sss := r.FindAllStringSubmatch(s, -1)
out2 := make([]string, len(sss))
for i, v := range sss {
out2[i] = v[1]
}
fmt.Printf("%q\n", out2)
这也将得到所需的输出:
["echo" "-n" "\"a b c d\""]
在Go Playground上尝试一下吧。
英文:
This can be expressed using regular expression in a very compact way.
The input (command) is a series of tokens that are:
- either non-quoted and cannot contain quotes and spaces,
- or quoted and spawn until the next quotation mark and can contain spaces (but not quotation mark).
And:
- Tokens are separated by spaces, or the end of input.
The regular expression from the listed criteria:
("[^"]*"|[^"\s]+)(\s+|$)
Criteria: __2____ __1___ __3__
Using Go's regexp
package the solution is quite short:
s := `echo -n "a b c d"`
pattern := `("[^"]*"|[^"\s]+)(\s+|$)`
r := regexp.MustCompile(pattern)
fmt.Printf("%q\n", r.FindAllStringSubmatch(s, -1))
fmt.Printf("%q\n", r.FindAllString(s, -1))
Output (try it on the Go Playground):
[["echo " "echo" " "] ["-n " "-n" " "] ["\"a b c d\"" "\"a b c d\"" ""]]
["echo " "-n " "\"a b c d\""]
Note that the result of regexp.FindAllString()
also contains the delimeters (spaces) between tokens, so you may call strings.TrimSpace()
on them to remove those:
ss := r.FindAllString(s, -1)
out1 := make([]string, len(ss))
for i, v := range ss {
out1[i] = strings.TrimSpace(v)
}
fmt.Printf("%q\n", out1)
Which gives the desired output:
["echo" "-n" "\"a b c d\""]
Or you may use the result of regexp.FindAllStringSubmatch()
: it returns a slice of slices, use the 2nd element (at index 1
) from each element:
sss := r.FindAllStringSubmatch(s, -1)
out2 := make([]string, len(sss))
for i, v := range sss {
out2[i] = v[1]
}
fmt.Printf("%q\n", out2)
Which also gives the desired output:
["echo" "-n" "\"a b c d\""]
Try these on the Go Playground).
答案2
得分: -3
如果字符串固定有3个参数,你可以使用strings.SplitN
来实现。这里是关于Go语言字符串库的完整文档。
https://golang.org/pkg/strings/#SplitN
如果我有任何错误,请指正。^^
英文:
If the string are fix have 3 parameters you can do by strings.SplitN
. here are the full documentation about strings library of golang.
https://golang.org/pkg/strings/#SplitN
CMIIW ^^
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论