如何从命令行字符串中获取类似于os.Args的标记

huangapple go评论81阅读模式
英文:

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

这可以用正则表达式以非常简洁的方式表示。

输入(命令)是一系列的标记,它们可以是:

  1. 非引号标记,不能包含引号和空格,
  2. 或者被引号包围的标记,直到下一个引号标记,可以包含空格(但不能包含引号)。

并且:

  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:

  1. either non-quoted and cannot contain quotes and spaces,
  2. or quoted and spawn until the next quotation mark and can contain spaces (but not quotation mark).

And:

  1. 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 ^^

huangapple
  • 本文由 发表于 2017年4月21日 15:36:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/43536673.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定