github.com/2lambda123/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  }