gitee.com/h79/goutils@v1.22.10/common/stringutil/string.go (about)

     1  package stringutil
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"fmt"
     7  	"reflect"
     8  	"regexp"
     9  	"strconv"
    10  	"strings"
    11  )
    12  
    13  type Builder struct {
    14  	strings.Builder
    15  }
    16  
    17  func (b *Builder) WriteUInt64(n uint64) (int, error) {
    18  	return b.WriteString(UInt64ToString(n))
    19  }
    20  
    21  func (b *Builder) WriteInt64(n int64) (int, error) {
    22  	return b.WriteString(Int64ToString(n))
    23  }
    24  
    25  func (b *Builder) WriteUInt32(n uint32) (int, error) {
    26  	return b.WriteString(UInt32ToString(n))
    27  }
    28  
    29  func (b *Builder) WriteInt32(n int32) (int, error) {
    30  	return b.WriteString(Int32ToString(n))
    31  }
    32  
    33  func (b *Builder) WriteUInt(n uint) (int, error) {
    34  	return b.WriteString(UInt32ToString(uint32(n)))
    35  }
    36  
    37  func (b *Builder) WriteInt(n int) (int, error) {
    38  	return b.WriteString(IntToString(n))
    39  }
    40  
    41  func (b *Builder) WriteF64(n float64) (int, error) {
    42  	return b.WriteString(F64ToString(n))
    43  }
    44  
    45  func StringToInt(a string) int {
    46  	if i, err := strconv.Atoi(a); err == nil {
    47  		return i
    48  	}
    49  	return 0
    50  }
    51  
    52  func StringToInt32(a string) int32 {
    53  	if i, err := strconv.ParseInt(a, 10, 64); err == nil {
    54  		return int32(i)
    55  	}
    56  	return 0
    57  }
    58  
    59  func StringToUInt32(a string) uint32 {
    60  	if i, err := strconv.ParseUint(a, 10, 64); err == nil {
    61  		return uint32(i)
    62  	}
    63  	return 0
    64  }
    65  
    66  func StringToInt64(a string) int64 {
    67  	if i, err := strconv.ParseInt(a, 10, 64); err == nil {
    68  		return i
    69  	}
    70  	return 0
    71  }
    72  
    73  func StringToUInt64(a string) uint64 {
    74  	if i, err := strconv.ParseUint(a, 10, 64); err == nil {
    75  		return i
    76  	}
    77  	return 0
    78  }
    79  
    80  func IntToString(a int) string {
    81  	return strconv.Itoa(a)
    82  }
    83  
    84  func UInt32ToString(a uint32) string {
    85  	return strconv.FormatUint(uint64(a), 10)
    86  }
    87  
    88  func Int32ToString(a int32) string {
    89  	return strconv.FormatInt(int64(a), 10)
    90  }
    91  
    92  func UInt64ToString(a uint64) string {
    93  	return strconv.FormatUint(a, 10)
    94  }
    95  
    96  func Int64ToString(a int64) string {
    97  	return strconv.FormatInt(a, 10)
    98  }
    99  
   100  func F64ToString(a float64) string {
   101  	return F64ToStringV(a, 2, 64)
   102  }
   103  
   104  func F64ToStringV(a float64, prec, bitSize int) string {
   105  	return strconv.FormatFloat(a, 'f', prec, bitSize)
   106  }
   107  
   108  func StringToF64(a string) float64 {
   109  	return StringToF64V(a, 64)
   110  }
   111  
   112  func Decimal(f float64) float64 {
   113  	f, err := strconv.ParseFloat(fmt.Sprintf("%.3f", f), 64)
   114  	if err != nil {
   115  		return 0.0
   116  	}
   117  	return f
   118  }
   119  
   120  func StringToF64V(a string, bitSize int) float64 {
   121  	f, err := strconv.ParseFloat(a, bitSize)
   122  	if err != nil {
   123  		return 0.0
   124  	}
   125  	return f
   126  }
   127  
   128  func DefaultString(a string, def string) string {
   129  	if a == "" {
   130  		return def
   131  	}
   132  	return a
   133  }
   134  
   135  func UInt32ToBytes(n uint32) []byte {
   136  	return ToBytes[uint32](n)
   137  }
   138  
   139  func BytesToUInt32(bys []byte) uint32 {
   140  	return binary.BigEndian.Uint32(bys)
   141  }
   142  
   143  func UInt64ToBytes(n uint64) []byte {
   144  	return ToBytes[uint64](n)
   145  }
   146  
   147  func BytesToUInt64(bys []byte) uint64 {
   148  	return binary.BigEndian.Uint64(bys)
   149  }
   150  
   151  // BytesTo BType not int
   152  func BytesTo[T BType](bys []byte, def T) T {
   153  	var data T
   154  	buf := bytes.NewBuffer(bys)
   155  	if er := binary.Read(buf, binary.BigEndian, &data); er != nil {
   156  		return def
   157  	}
   158  	return data
   159  }
   160  
   161  func ToBytes[T BType](n T) []byte {
   162  	buf := bytes.NewBuffer([]byte{})
   163  	if er := binary.Write(buf, binary.BigEndian, n); er != nil {
   164  		return nil
   165  	}
   166  	return buf.Bytes()
   167  }
   168  
   169  type BType interface {
   170  	int8 | int16 | int32 | int64 |
   171  		uint8 | uint16 | uint32 | uint64 |
   172  		float64 | float32 | bool
   173  }
   174  
   175  const (
   176  	// 带分机号
   177  	regPhoneExt = "^(13\\d|15\\d|17\\d|18\\d|16\\d|19\\d|14\\d)\\d{8}(-\\d{3,6})$"
   178  	regPhone    = "^(13\\d|15\\d|17\\d|18\\d|16\\d|19\\d|14\\d)\\d{8}(-\\d{3,6})?$"
   179  	regEmail    = "^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+"
   180  	regName     = "^[a-z0-9_-]{3,20}$"
   181  )
   182  
   183  var (
   184  	emailCompile    = regexp.MustCompile(regEmail)
   185  	phoneCompile    = regexp.MustCompile(regPhone)
   186  	phoneExtCompile = regexp.MustCompile(regPhoneExt)
   187  	nameCompile     = regexp.MustCompile(regName)
   188  
   189  	hasHKPhoneCompile    = regexp.MustCompile("(5|6|8|9)\\d{7}")
   190  	hasChinaPhoneCompile = regexp.MustCompile("(13\\d|15\\d|17\\d|18\\d|16\\d|19\\d|14\\d)\\d{8}")
   191  )
   192  
   193  // IsEmailValidate 邮箱合规
   194  func IsEmailValidate(email string) bool {
   195  	return emailCompile.MatchString(email)
   196  }
   197  
   198  // IsPhoneValidate 手机验证
   199  func IsPhoneValidate(mobile string) bool {
   200  	return phoneCompile.MatchString(mobile)
   201  }
   202  
   203  // IsPhoneExtValidate 带分机
   204  func IsPhoneExtValidate(mobile string) bool {
   205  	return phoneExtCompile.MatchString(mobile)
   206  }
   207  
   208  // IsNameValidate 用户名验证
   209  func IsNameValidate(name string) bool {
   210  	return nameCompile.MatchString(name)
   211  }
   212  
   213  /**
   214   * 字符串是否有手机
   215   * \d 匹配一个或多个数字,其中 \ 要转义,所以是 \\d
   216   * $ 匹配输入字符串结尾的位置
   217   */
   218  
   219  func HasPhoneLegal(num string) bool {
   220  	return HasChinaPhoneLegal(num) || HasHKPhoneLegal(num)
   221  }
   222  
   223  func HasChinaPhoneLegal(num string) bool {
   224  	return hasChinaPhoneCompile.MatchString(num)
   225  }
   226  
   227  func GetChinaPhone(num string) string {
   228  	return hasChinaPhoneCompile.FindString(num)
   229  }
   230  
   231  func HasHKPhoneLegal(num string) bool {
   232  	return hasHKPhoneCompile.MatchString(num)
   233  }
   234  
   235  func GetHKPhone(num string) string {
   236  	return hasHKPhoneCompile.FindString(num)
   237  }
   238  
   239  type Number struct {
   240  	Num     int64
   241  	Decimal float64
   242  }
   243  
   244  func NumberWithI64(v int64) Number {
   245  	return Number{Num: v}
   246  }
   247  
   248  func NumberWithF64(v float64, prec int) Number {
   249  	var ff = strings.Split(F64ToStringV(v, prec, 64), ".")
   250  	return Number{Num: StringToInt64(ff[0]), Decimal: StringToF64("0." + ff[1])}
   251  }
   252  
   253  func NumberWithString(number string, prec int) Number {
   254  	if strings.HasSuffix(number, "%") {
   255  		return NumberWithF64(StringToF64(strings.TrimSuffix(number, "%"))/100, prec)
   256  	}
   257  	if strings.HasPrefix(number, "%") {
   258  		return NumberWithF64(StringToF64(strings.TrimPrefix(number, "%"))/100, prec)
   259  	}
   260  	var nr = Number{Decimal: 0}
   261  	sp := strings.SplitN(number, ".", 2)
   262  	if len(sp) >= 2 { //有小数点
   263  		nr.Decimal = StringToF64("0." + sp[1])
   264  	}
   265  	nr.Num = StringToInt64(sp[0])
   266  	return nr
   267  }
   268  
   269  func (n Number) String() string {
   270  	return n.ToString(4)
   271  }
   272  
   273  func (n Number) ToString(prec int) string {
   274  	var out = ""
   275  	if n.Num > 0 {
   276  		out = Int64ToString(n.Num)
   277  	} else if n.Num == 0 {
   278  		out = "0"
   279  	}
   280  	if n.Decimal <= 0 {
   281  		return out
   282  	}
   283  	dec := F64ToStringV(n.Decimal, prec, 64)
   284  	ff := strings.Split(dec, ".")
   285  	if ff[0] == "0" {
   286  		out += "." + ff[1]
   287  	} else {
   288  		out += "." + ff[0]
   289  	}
   290  	return out
   291  }
   292  
   293  func (n Number) ToF64(prec int) float64 {
   294  	return StringToF64(n.ToString(prec))
   295  }
   296  
   297  func (n Number) ToI64() int64 {
   298  	return int64(StringToF64(n.ToString(0)))
   299  }
   300  
   301  func NumberValue(number string) (num int64, decimal float64) {
   302  	var n = NumberWithString(number, 4)
   303  	return n.Num, n.Decimal
   304  }
   305  
   306  // PercentIf
   307  // 是否按比例分,是返回,比例值,true
   308  func PercentIf(number string) (float64, bool) {
   309  	num, decimal := NumberValue(number)
   310  	if num == 0 {
   311  		return decimal, true
   312  	}
   313  	return float64(num), false
   314  }
   315  
   316  func ATo(arr []interface{}) []string {
   317  	var res = make([]string, len(arr))
   318  	for i := range arr {
   319  		res[i] = ToString(arr[i])
   320  	}
   321  	return res
   322  }
   323  
   324  func ToString(value interface{}) string {
   325  	reflectValue := reflect.Indirect(reflect.ValueOf(value))
   326  	return ToStringV2(reflectValue)
   327  }
   328  
   329  func ToStringV2(reflectValue reflect.Value) string {
   330  
   331  	switch reflectValue.Kind() {
   332  	case reflect.String:
   333  		return reflectValue.String()
   334  
   335  	case reflect.Int:
   336  		fallthrough
   337  	case reflect.Int8:
   338  		fallthrough
   339  	case reflect.Int16:
   340  		fallthrough
   341  	case reflect.Int32:
   342  		fallthrough
   343  	case reflect.Int64:
   344  		return strconv.FormatInt(reflectValue.Int(), 10)
   345  
   346  	case reflect.Uint:
   347  		fallthrough
   348  	case reflect.Uint8:
   349  		fallthrough
   350  	case reflect.Uint16:
   351  		fallthrough
   352  	case reflect.Uint32:
   353  		fallthrough
   354  	case reflect.Uint64:
   355  		return strconv.FormatUint(reflectValue.Uint(), 10)
   356  
   357  	case reflect.Float32:
   358  		fallthrough
   359  	case reflect.Float64:
   360  		return strconv.FormatFloat(reflectValue.Float(), 'f', 5, 64)
   361  
   362  	case reflect.Bool:
   363  		if reflectValue.Bool() {
   364  			return "true"
   365  		} else {
   366  			return "false"
   367  		}
   368  	default:
   369  		msg := fmt.Sprintf("not support the '%v' data", reflectValue.Kind())
   370  		panic(msg)
   371  	}
   372  	return ""
   373  }