github.com/kaydxh/golang@v0.0.131/go/strings/strings.go (about)

     1  /*
     2   *Copyright (c) 2022, kaydxh
     3   *
     4   *Permission is hereby granted, free of charge, to any person obtaining a copy
     5   *of this software and associated documentation files (the "Software"), to deal
     6   *in the Software without restriction, including without limitation the rights
     7   *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     8   *copies of the Software, and to permit persons to whom the Software is
     9   *furnished to do so, subject to the following conditions:
    10   *
    11   *The above copyright notice and this permission notice shall be included in all
    12   *copies or substantial portions of the Software.
    13   *
    14   *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    15   *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    16   *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    17   *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    18   *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    19   *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    20   *SOFTWARE.
    21   */
    22  package strings
    23  
    24  import (
    25  	"fmt"
    26  	"strings"
    27  	"unicode/utf8"
    28  
    29  	strconv_ "github.com/kaydxh/golang/go/strconv"
    30  )
    31  
    32  func GetStringOrFallback(values ...string) string {
    33  	for _, v := range values {
    34  		if v != "" {
    35  			return v
    36  		}
    37  	}
    38  
    39  	return ""
    40  }
    41  
    42  /*
    43  func Replace(s string, old string, news []string, n int) string {
    44  	if len(news) == 0 || n == 0 {
    45  		return s
    46  	}
    47  
    48  	if m := strings.Count(s, old); m == 0 {
    49  		return s // avoid allocation
    50  	} else if n < 0 || m < n {
    51  		n = m
    52  	}
    53  	// if len(news) < n , padding news use last element in news
    54  	for i := 0; i < n-len(news); i++ {
    55  		news = append(news, news[len(news)-1])
    56  	}
    57  
    58  	incLen := 0
    59  	for i := 0; i < n; i++ {
    60  		incLen += len(news[i]) - len(old)
    61  	}
    62  
    63  	// Apply replacements to buffer.
    64  	var b strings.Builder
    65  	b.Grow(len(s) + incLen)
    66  	start := 0
    67  	for i := 0; i < n; i++ {
    68  		j := start
    69  		if len(old) == 0 {
    70  			if i > 0 {
    71  				_, wid := utf8.DecodeRuneInString(s[start:])
    72  				j += wid
    73  			}
    74  		} else {
    75  			j += strings.Index(s[start:], old)
    76  		}
    77  		b.WriteString(s[start:j])
    78  		b.WriteString(news[i])
    79  		start = j + len(old)
    80  	}
    81  	b.WriteString(s[start:])
    82  	return b.String()
    83  
    84  }
    85  */
    86  
    87  /*
    88  func ReplaceAll(s, old string, news []string) string {
    89  	return Replace(s, old, news, -1)
    90  }
    91  */
    92  
    93  func Replace(s string, old string, news []interface{}, useQuote bool, n int) string {
    94  	if len(news) == 0 || n == 0 {
    95  		return s
    96  	}
    97  
    98  	if m := strings.Count(s, old); m == 0 {
    99  		return s // avoid allocation
   100  	} else if n < 0 || m < n {
   101  		n = m
   102  	}
   103  	// if len(news) < n , padding news use last element in news
   104  	for i := 0; i < n-len(news); i++ {
   105  		news = append(news, news[len(news)-1])
   106  	}
   107  
   108  	var b strings.Builder
   109  	start := 0
   110  	for i := 0; i < n; i++ {
   111  		j := start
   112  		if len(old) == 0 {
   113  			if i > 0 {
   114  				_, wid := utf8.DecodeRuneInString(s[start:])
   115  				j += wid
   116  			}
   117  		} else {
   118  			j += strings.Index(s[start:], old)
   119  		}
   120  		b.WriteString(s[start:j])
   121  		if useQuote {
   122  			b.WriteString(fmt.Sprintf(`"%v"`, news[i]))
   123  		} else {
   124  			b.WriteString(fmt.Sprintf("%v", news[i]))
   125  		}
   126  		start = j + len(old)
   127  	}
   128  	b.WriteString(s[start:])
   129  	return b.String()
   130  
   131  }
   132  
   133  func ReplaceAll(s, old string, news []interface{}, useQuote bool) string {
   134  	return Replace(s, old, news, useQuote, -1)
   135  }
   136  
   137  // Split slices s into all substrings separated by sep and returns a slice of
   138  // the substrings between those separators.
   139  //
   140  // If s does not contain sep and sep is not empty, Split returns a
   141  // slice of length 0.
   142  //
   143  // If sep is empty, Split splits after each UTF-8 sequence. If both s
   144  // and sep are empty, Split returns an empty slice.
   145  //
   146  // It is equivalent to SplitN with a count of -1.
   147  func SplitOmitEmpty(s, sep string) []string {
   148  	var res []string
   149  	a := strings.Split(s, sep)
   150  	for _, v := range a {
   151  		if v != "" {
   152  			res = append(res, v)
   153  		}
   154  	}
   155  
   156  	return res
   157  }
   158  
   159  // Split2 returns the values from strings.SplitN(s, sep, 2).
   160  // If sep is not found, it returns ("", "", false) instead.
   161  func Split2(s, sep string) (string, string, bool) {
   162  	spl := strings.SplitN(s, sep, 2)
   163  	if len(spl) < 2 {
   164  		return "", "", false
   165  	}
   166  	return spl[0], spl[1], true
   167  }
   168  
   169  func SplitToNums[T any](s, sep string, convert func(string) (T, error)) ([]T, error) {
   170  	ss := SplitOmitEmpty(s, sep)
   171  	return strconv_.ParseNums(ss, convert)
   172  }
   173  
   174  func EqualCaseInsensitive(src, dst string) bool {
   175  	return strings.ToLower(src) == strings.ToLower(dst)
   176  }
   177  
   178  func EmptyString(str string) bool {
   179  	return strings.TrimSpace(str) == ""
   180  }