diff --git a/tools/str_tools.go b/tools/str_tools.go index 8eb81268..5d10acad 100644 --- a/tools/str_tools.go +++ b/tools/str_tools.go @@ -5,7 +5,7 @@ import "regexp" var ( // quoteFieldRe greedily matches between matching pairs of '', "", or // non-word characters. - quoteFieldRe = regexp.MustCompile("'.+'|\".+\"|\\S+") + quoteFieldRe = regexp.MustCompile("'(.+)'|\"(.+)\"|(\\S+)") ) // QuotedFields is an alternative to strings.Fields (see: @@ -13,10 +13,25 @@ var ( // pairs of quotation delimeters. // // For instance, the quoted fields of the string "foo bar 'baz etc'" would be: -// []string{"foo", "bar", "'baz etc'"} +// []string{"foo", "bar", "baz etc"} // // Whereas the same argument given to strings.Fields, would return: // []string{"foo", "bar", "'baz", "etc'"} func QuotedFields(s string) []string { - return quoteFieldRe.FindAllString(s, -1) + submatches := quoteFieldRe.FindAllStringSubmatch(s, -1) + out := make([]string, 0, len(submatches)) + + for _, matches := range submatches { + var str string + for _, m := range matches[1:] { + if len(m) > 0 { + str = m + break + } + } + + out = append(out, str) + } + + return out } diff --git a/tools/str_tools_test.go b/tools/str_tools_test.go index f62c8f0d..f1638f47 100644 --- a/tools/str_tools_test.go +++ b/tools/str_tools_test.go @@ -26,25 +26,25 @@ func TestQuotedFields(t *testing.T) { "simple trailing": {"foo bar ", []string{"foo", "bar"}}, "simple leading": {" foo bar", []string{"foo", "bar"}}, - "single quotes": {"foo 'bar baz'", []string{"foo", "'bar baz'"}}, - "single quotes trailing": {"foo 'bar baz' ", []string{"foo", "'bar baz'"}}, - "single quotes leading": {" foo 'bar baz'", []string{"foo", "'bar baz'"}}, + "single quotes": {"foo 'bar baz'", []string{"foo", "bar baz"}}, + "single quotes trailing": {"foo 'bar baz' ", []string{"foo", "bar baz"}}, + "single quotes leading": {" foo 'bar baz'", []string{"foo", "bar baz"}}, - "double quotes": {"foo \"bar baz\"", []string{"foo", "\"bar baz\""}}, - "double quotes trailing": {"foo \"bar baz\" ", []string{"foo", "\"bar baz\""}}, - "double quotes leading": {" foo \"bar baz\"", []string{"foo", "\"bar baz\""}}, + "double quotes": {"foo \"bar baz\"", []string{"foo", "bar baz"}}, + "double quotes trailing": {"foo \"bar baz\" ", []string{"foo", "bar baz"}}, + "double quotes leading": {" foo \"bar baz\"", []string{"foo", "bar baz"}}, - "nested single quotes": {"foo 'bar 'baz''", []string{"foo", "'bar 'baz''"}}, - "nested single quotes trailing": {"foo 'bar 'baz'' ", []string{"foo", "'bar 'baz''"}}, - "nested single quotes leading": {" foo 'bar 'baz''", []string{"foo", "'bar 'baz''"}}, + "nested single quotes": {"foo 'bar 'baz''", []string{"foo", "bar 'baz'"}}, + "nested single quotes trailing": {"foo 'bar 'baz'' ", []string{"foo", "bar 'baz'"}}, + "nested single quotes leading": {" foo 'bar 'baz''", []string{"foo", "bar 'baz'"}}, - "nested double quotes": {"foo \"bar \"baz\"\"", []string{"foo", "\"bar \"baz\"\""}}, - "nested double quotes trailing": {"foo \"bar \"baz\"\" ", []string{"foo", "\"bar \"baz\"\""}}, - "nested double quotes leading": {" foo \"bar \"baz\"\"", []string{"foo", "\"bar \"baz\"\""}}, + "nested double quotes": {"foo \"bar \"baz\"\"", []string{"foo", "bar \"baz\""}}, + "nested double quotes trailing": {"foo \"bar \"baz\"\" ", []string{"foo", "bar \"baz\""}}, + "nested double quotes leading": {" foo \"bar \"baz\"\"", []string{"foo", "bar \"baz\""}}, - "mixed quotes": {"foo 'bar \"baz\"'", []string{"foo", "'bar \"baz\"'"}}, - "mixed quotes trailing": {"foo 'bar \"baz\"' ", []string{"foo", "'bar \"baz\"'"}}, - "mixed quotes leading": {" foo 'bar \"baz\"'", []string{"foo", "'bar \"baz\"'"}}, + "mixed quotes": {"foo 'bar \"baz\"'", []string{"foo", "bar \"baz\""}}, + "mixed quotes trailing": {"foo 'bar \"baz\"' ", []string{"foo", "bar \"baz\""}}, + "mixed quotes leading": {" foo 'bar \"baz\"'", []string{"foo", "bar \"baz\""}}, } { t.Log(desc) c.Assert(t)