github.com/x-oss-byte/git-lfs@v2.5.2+incompatible/tools/str_tools.go (about) 1 package tools 2 3 import ( 4 "regexp" 5 "strings" 6 ) 7 8 var ( 9 // quoteFieldRe greedily matches between matching pairs of '', "", or 10 // non-word characters. 11 quoteFieldRe = regexp.MustCompile("'(.*)'|\"(.*)\"|(\\S*)") 12 ) 13 14 // QuotedFields is an alternative to strings.Fields (see: 15 // https://golang.org/pkg/strings#Fields) that respects spaces between matching 16 // pairs of quotation delimeters. 17 // 18 // For instance, the quoted fields of the string "foo bar 'baz etc'" would be: 19 // []string{"foo", "bar", "baz etc"} 20 // 21 // Whereas the same argument given to strings.Fields, would return: 22 // []string{"foo", "bar", "'baz", "etc'"} 23 func QuotedFields(s string) []string { 24 submatches := quoteFieldRe.FindAllStringSubmatch(s, -1) 25 out := make([]string, 0, len(submatches)) 26 27 for _, matches := range submatches { 28 // if a leading or trailing space is found, ignore that 29 if matches[0] == "" { 30 continue 31 } 32 33 // otherwise, find the first non-empty match (inside balanced 34 // quotes, or a space-delimited string) 35 var str string 36 for _, m := range matches[1:] { 37 if len(m) > 0 { 38 str = m 39 break 40 } 41 } 42 43 out = append(out, str) 44 } 45 46 return out 47 } 48 49 // Ljust returns a copied string slice where each element is left justified to 50 // match the width of the longest element in the set. 51 func Ljust(strs []string) []string { 52 llen := len(Longest(strs)) 53 54 dup := make([]string, len(strs), cap(strs)) 55 copy(dup, strs) 56 57 for i, str := range strs { 58 width := MaxInt(0, llen-len(str)) 59 padding := strings.Repeat(" ", width) 60 61 dup[i] = str + padding 62 } 63 64 return dup 65 } 66 67 // Rjust returns a copied string slice where each element is right justified to 68 // match the width of the longest element in the set. 69 func Rjust(strs []string) []string { 70 llen := len(Longest(strs)) 71 72 dup := make([]string, len(strs), cap(strs)) 73 copy(dup, strs) 74 75 for i, str := range strs { 76 width := MaxInt(0, llen-len(str)) 77 padding := strings.Repeat(" ", width) 78 79 dup[i] = padding + str 80 } 81 82 return dup 83 } 84 85 // Longest returns the longest element in the string slice in O(n) time and O(1) 86 // space. If strs is empty or nil, an empty string will be returned. 87 func Longest(strs []string) string { 88 if len(strs) == 0 { 89 return "" 90 } 91 92 var longest string 93 var llen int 94 for _, str := range strs { 95 if len(str) >= llen { 96 longest = str 97 llen = len(longest) 98 } 99 } 100 101 return longest 102 } 103 104 // Indent returns a string which prepends "\t" TAB characters to the beginning 105 // of each line in the given string "str". 106 func Indent(str string) string { 107 indented := strings.Replace(str, "\n", "\n\t", -1) 108 if len(indented) > 0 { 109 indented = "\t" + indented 110 } 111 112 return indented 113 } 114 115 var ( 116 tabRe = regexp.MustCompile(`(?m)^[ \t]+`) 117 ) 118 119 // Undent removes all leading tabs in the given string "str", line-wise. 120 func Undent(str string) string { 121 return tabRe.ReplaceAllString(str, "") 122 }