如何从命令行字符串中获取os.Args-like标记

时间:2017-04-21 07:36:55

标签: string go token string-parsing

我有一个字符串变量:

commandLineString := `echo -n "a b c d"`

我想将其转换为:

args := []string{"echo", "-n", "\"a b c d\""}

我该怎么做?

2 个答案:

答案 0 :(得分:0)

这可以使用regular expression以非常紧凑的方式表达。

输入(命令)是一系列令牌:

  1. 要么不带引号,又不能包含引号和空格,
  2. 或引用并生成,直到下一个引号,并且可以包含空格(但不能包含引号)。
    1. 标记由空格或输入结束分隔。
    2. 列出的标准中的正则表达式:

                 ("[^"]*"|[^"\s]+)(\s+|$)
      
      Criteria:   __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上尝试这些。

答案 1 :(得分:-3)

如果字符串已修复,则可以通过strings.SplitN执行3个参数。这里是关于golang字符串库的完整文档。 https://golang.org/pkg/strings/#SplitN

CMIIW ^^