github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zstring/expand.go (about) 1 package zstring 2 3 func Expand(s string, process func(key string) string) string { 4 var buf []byte 5 i := 0 6 for j := 0; j < len(s); j++ { 7 if s[j] == '$' && j+1 < len(s) { 8 if buf == nil { 9 buf = make([]byte, 0, 2*len(s)) 10 } 11 buf = append(buf, s[i:j]...) 12 name, w := getShellName(s[j+1:]) 13 if name != "" { 14 buf = append(buf, process(name)...) 15 } else if w == 0 { 16 buf = append(buf, s[j]) 17 } 18 j += w 19 i = j + 1 20 } 21 } 22 23 if buf == nil { 24 return s 25 } 26 27 return Bytes2String(buf) + s[i:] 28 } 29 30 func getShellName(s string) (string, int) { 31 switch { 32 case s[0] == '{': 33 if len(s) > 2 && isShellSpecialVar(s[1]) && s[2] == '}' { 34 return s[1:2], 3 35 } 36 for i := 1; i < len(s); i++ { 37 if s[i] == '}' { 38 if i == 1 { 39 return "", 2 40 } 41 return s[1:i], i + 1 42 } 43 } 44 return "", 1 45 case isShellSpecialVar(s[0]): 46 return s[0:1], 1 47 } 48 var i int 49 for i = 0; i < len(s) && isAlphaNum(s[i]); i++ { 50 } 51 return s[:i], i 52 } 53 54 func isShellSpecialVar(c uint8) bool { 55 switch c { 56 case '*', '#', '$', '@', '!', '?', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': 57 return true 58 } 59 return false 60 } 61 62 func isAlphaNum(c uint8) bool { 63 return c == '_' || '0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' 64 }