使用Go解析类似命令行参数的字符串

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

Parse strings like command line arguments with Go

问题

如何将一个字符串解析为一系列命令行参数?我想要能够将一个字符串解析为带有标志(flag)和/或pflag的参数。我该如何做?

package main

import (
	"fmt"
	"os"

	flag "github.com/spf13/pflag"
)

func main() {
	command := `unimportant -fb "quoted string"`
	var (
		foo bool
		bar string
	)
	flag.BoolVarP(&foo, "foo", "f", false, "foo")
	flag.StringVarP(&bar, "bar", "b", "default", "bar")

	// 解析命令
	os.Args = append(os.Args, "-fb", "quoted string")
	flag.Parse()

	fmt.Println(command)
	fmt.Println("foo", foo)
	fmt.Println("bar", bar)
}

以上代码演示了如何使用github.com/spf13/pflag包来解析命令行参数。在这个例子中,字符串command被解析为命令行参数,并使用flag.BoolVarPflag.StringVarP函数定义了两个参数foobar。然后,通过将-fb"quoted string"添加到os.Args中,并调用flag.Parse()来解析命令行参数。最后,打印出解析后的参数值。

英文:

How do I take a string and parse it as if it was a series of command line arguments? I want to be able to take a string and parse that with flag and/or pflag. How do I do this?

package main

import (
	"fmt"
	"os"

	flag "github.com/spf13/pflag"
)

func main() {
	command := `unimportant -fb "quoted string"`
	var (
		foo bool
		bar string
	)
	flag.BoolVarP(&foo, "foo", "f", false, "foo")
	flag.StringVarP(&bar, "bar", "b", "default", "bar")

	// Parse command
	os.Args = append(os.Args, "-fb", "quoted string")
	flag.Parse()

	fmt.Println(command)
	fmt.Println("foo", foo)
	fmt.Println("bar", bar)
}

答案1

得分: 4

最简单的方法是使用shellwords包将字符串解析为shell单词的argv,然后使用除flagpflag之外的命令行解析器来解析任意的argv(例如flags,但有很多选择)。

// 将你的字符串解析为一个[]string,就像shell一样。

argv, err := shellwords.Parse("./foo --bar=baz")
// argv 应该是["./foo", "--bar=baz"]

...

// 在这里定义你的选项等

...

extraArgs, err := flags.ParseArgs(&opts, argv)
英文:

The easiest way would be use the package shellwords to parse your string into an argv of shell words, and then use a command-line parser other than flag or pflag that supports parsing an arbitrary argv (say flags, but there are many to choose from.)

// Parse  your string into an []string as the shell would.

argv, err := shellwords.Parse("./foo --bar=baz")
// argv should be ["./foo", "--bar=baz"]

...

// define your options, etc. here

...

extraArgs, err := flags.ParseArgs(&opts, argv)

答案2

得分: 0

正则表达式可以用来检测每个参数。参数有两种可能的形式:

  1. 一组字母和一个负号:[-a-zA-Z]+
  2. 夹在两个引号之间的内容:".*?"

关于regexp包的信息:https://pkg.go.dev/regexp

关于regexp语法的信息:https://pkg.go.dev/regexp/syntax@go1.17.6

re := regexp.MustCompile(`([-a-zA-Z]+)|(".*?[^\\]")|("")`)
command := `unimportant -fb "quoted string"`

allArgs := re.FindAllString(command, -1)

//fmt.Printf("%+v\n", allArgs)

// 去除引号
for _, arg := range allArgs {
	if arg[0] == ''"' {
		arg = arg[1 : len(arg)-1]
	}
	fmt.Println(arg)
}

输出:

unimportant
-fb
quoted string
英文:

Regex can use to detect each argument. There are two possible forms for an argument:

  1. a group of letters and a negative sign: [-a-zA-Z]+
  2. something sandwiched between two ": ".*?"

Information about regexp package: https://pkg.go.dev/regexp

Information about regexp syntax: https://pkg.go.dev/regexp/syntax@go1.17.6

re := regexp.MustCompile(`([-a-zA-Z]+)|(".*?[^\\]")|("")`)
command := `unimportant -fb "quoted string"`

allArgs := re.FindAllString(command, -1)

//fmt.Printf("%+v\n", allArgs)

// to remove "
for _, arg := range allArgs {
	if arg[0] == '"' {
		arg = arg[1 : len(arg)-1]
	}
	fmt.Println(arg)
}

Output:

unimportant
-fb
quoted string

huangapple
  • 本文由 发表于 2022年2月4日 12:36:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/70981456.html
匿名

发表评论

匿名网友

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

确定