• golang 一个字符串表达式替换的函数


    package util
    
    import (
    	"fmt"
    	"reflect"
    	"regexp"
    	"strconv"
    	"strings"
    )
    
    func floatToString(f float64) string {
    	return strconv.FormatFloat(f, 'E', -1, 64)
    }
    func intToString(i int64) string {
    	return strconv.FormatInt(i, 10)
    }
    func boolToString(b bool) string {
    	if b {
    		return "true"
    	} else {
    		return "false"
    	}
    }
    
    func toString(arg interface{}) string {
    	switch arg.(type) {
    	case bool:
    		return boolToString(arg.(bool))
    	case float32:
    		return floatToString(float64(arg.(float32)))
    	case float64:
    		return floatToString(arg.(float64))
    		//case complex64:
    		//	p.fmtComplex(complex128(f), 64, verb)
    		//case complex128:
    		//	p.fmtComplex(f, 128, verb)
    	case int:
    		return intToString(int64(arg.(int)))
    	case int8:
    		return intToString(int64(arg.(int8)))
    	case int16:
    		return intToString(int64(arg.(int16)))
    	case int32:
    		return intToString(int64(arg.(int32)))
    	case int64:
    		return intToString(int64(arg.(int64)))
    	default:
    		return fmt.Sprint(arg)
    	}
    }
    
    func combinePath(pre string, path string) string {
    	if pre != "" && path != "" {
    		return pre + "." + path
    	}
    	return pre + path
    }
    
    //将一个map[string]interface打平
    func FlatMap(prefix string, mapData map[string]interface{}) map[string]interface{} {
    	v := reflect.ValueOf(mapData)
    	res := make(map[string]interface{})
    	foreachObj(prefix, v, res)
    	return res
    }
    
    func foreachObj(pre string, v reflect.Value, res map[string]interface{}) {
    	switch v.Kind() {
    	case reflect.Ptr:
    		foreachObj(pre, v.Elem(), res)
    	case reflect.Array, reflect.Slice:
    		for i := 0; i < v.Len(); i++ {
    			foreachObj(combinePath(pre, strconv.Itoa(i)), v.Index(i), res)
    		}
    	case reflect.Struct:
    		vType := v.Type()
    		for i := 0; i < v.NumField(); i++ {
    			foreachObj(combinePath(pre, vType.Field(i).Name), v.Field(i), res)
    		}
    	case reflect.Map:
    		for _, key := range v.MapKeys() {
    			foreachObj(combinePath(pre, key.String()), v.MapIndex(key), res)
    		}
    	case reflect.Interface:
    		foreachObj(combinePath(pre, ""), v.Elem(), res)
    	default: // float, complex, bool, chan, string,int,func, interface
    		res[pre] = v.Interface()
    	}
    }
    
    func getTplExpressions(str string) []string {
    	reg_str := `${.*?}`
    	re, _ := regexp.Compile(reg_str)
    	all := re.FindAll([]byte(str), 2)
    	keyArrays := make([]string, 0)
    	for _, item := range all {
    		item_str := string(item)
    		if len(item_str) > 3 {
    			item_str = item_str[2 : len(item_str)-1]
    			keyArrays = append(keyArrays, item_str)
    		}
    
    	}
    	return keyArrays
    }
    
    // 将tpl中的占位符 替换为真实值 ${data.0.att1}
    func ParseTpl(tpl string, data map[string]interface{}) string {
    	if len(tpl) < 4 {
    		return tpl
    	}
    	expressions := getTplExpressions(tpl)
    	data = FlatMap("", data)
    	for _, exp := range expressions {
    		//fmt.Println("exp",exp)
    		exp = strings.TrimSpace(exp)
    		tpl = strings.Replace(tpl, "${"+exp+"}", toString(data[exp]), -1)
    	}
    	return tpl
    }
    

      

  • 相关阅读:
    零基础读懂视频播放器控制原理: ffplay 播放器源代码分析
    JPEG压缩原理与DCT离散余弦变换——有实际的数据演示
    图像压缩编码和解码原理——阐述了DCT变换的实质
    C++与C语言容易忽视的几个差异
    VLC目录结构介绍
    轻量便携流媒体播放器框架设计-2
    轻量便携流媒体播放器框架设计-1
    rtmp和rtsp的区别和适用范围
    vlc源码分析(六) 调用OpenMAX硬解码H.265
    vlc源码分析(五) 流媒体的音视频同步
  • 原文地址:https://www.cnblogs.com/mengxingxinqing/p/10939651.html
Copyright © 2020-2023  润新知