github.com/zlyuancn/zstr@v0.0.0-20230412074414-14d6b645962f/readme.md (about) 1 2 字符串转换工具, 类型转换工具, 模板渲染, 动态sql 3 4 --- 5 6 <!-- TOC --> 7 8 - [转换函数](#%E8%BD%AC%E6%8D%A2%E5%87%BD%E6%95%B0) 9 - [扫描函数](#%E6%89%AB%E6%8F%8F%E5%87%BD%E6%95%B0) 10 - [字符串工具](#%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%B7%A5%E5%85%B7) 11 - [模板渲染](#%E6%A8%A1%E6%9D%BF%E6%B8%B2%E6%9F%93) 12 - [示例](#%E7%A4%BA%E4%BE%8B) 13 - [变量名定义](#%E5%8F%98%E9%87%8F%E5%90%8D%E5%AE%9A%E4%B9%89) 14 - [渲染](#%E6%B8%B2%E6%9F%93) 15 - [值处理](#%E5%80%BC%E5%A4%84%E7%90%86) 16 - [变量](#%E5%8F%98%E9%87%8F) 17 - [模板匹配变量名方式](#%E6%A8%A1%E6%9D%BF%E5%8C%B9%E9%85%8D%E5%8F%98%E9%87%8F%E5%90%8D%E6%96%B9%E5%BC%8F) 18 - [变量名匹配优先级](#%E5%8F%98%E9%87%8F%E5%90%8D%E5%8C%B9%E9%85%8D%E4%BC%98%E5%85%88%E7%BA%A7) 19 - [动态sql](#%E5%8A%A8%E6%80%81sql) 20 - [示例](#%E7%A4%BA%E4%BE%8B) 21 - [模板语法说明](#%E6%A8%A1%E6%9D%BF%E8%AF%AD%E6%B3%95%E8%AF%B4%E6%98%8E) 22 - [操作符](#%E6%93%8D%E4%BD%9C%E7%AC%A6) 23 - [变量名](#%E5%8F%98%E9%87%8F%E5%90%8D) 24 - [标记](#%E6%A0%87%E8%AE%B0) 25 - [选项](#%E9%80%89%E9%A1%B9) 26 - [渲染](#%E6%B8%B2%E6%9F%93) 27 - [模板渲染和动态sql性能说明](#%E6%A8%A1%E6%9D%BF%E6%B8%B2%E6%9F%93%E5%92%8C%E5%8A%A8%E6%80%81sql%E6%80%A7%E8%83%BD%E8%AF%B4%E6%98%8E) 28 29 <!-- /TOC --> 30 31 --- 32 33 # 转换函数 34 35 支持 `string`, `[]byte`, `bool`, `int`, `int8`, `int16`, `int32`, `int64`, `uint`, `uint8`, `uint16`, `uint32`, `uint64`, `float32`, `float64`. 36 转换失败会返回该类型的零值. 37 38 ```go 39 zstr.GetString(1) // 1 40 zstr.GetBool(1) // true 41 zstr.GetInt(true) // 1 42 zstr.GetFloat32("3.2") // 3.2 43 zstr.Get... 44 ``` 45 46 转换失败时使用默认值 47 48 ```go 49 zstr.GetBool("xxx", true) // true 50 zstr.GetInt("xxx", 1) // 1 51 zstr.GetFloat32("xxx", float32(3.2)) // 3.2 52 zstr.Get... 53 ``` 54 55 Boolean转换说明 56 57 ```text 58 # 能转为true的数据 59 1, t, T, true, TRUE, True, y, Y, yes, YES, Yes, on, ON, On, ok, OK, Ok, enabled, ENABLED, Enabled 60 # 能转为false数据 61 nil, 0, f, F, false, FALSE, False, n, N, no, NO, No, off, OFF, Off, disable, DISABLE, Disable 62 ``` 63 64 --- 65 66 # 扫描函数 67 68 支持 `string`, `[]byte`, `bool`, `int`, `int8`, `int16`, `int32`, `int64`, `uint`, `uint8`, `uint16`, `uint32`, `uint64`, `float32`, `float64`. 69 70 将字符串扫描到指定变量 71 72 ``` 73 var a float64 74 var b uint32 75 var c bool 76 var d string 77 zstr.Scan("1", &a) // 1 78 zstr.Scan("1", &b) // 1 79 zstr.Scan("1", &c) // true 80 zstr.Scan("1", &d) // 1 81 ``` 82 83 将任何值扫描到指定变量 84 85 ``` 86 var a float64 87 var b uint32 88 var c bool 89 var d string 90 zstr.ScanAny(true, &a) // 1 91 zstr.ScanAny(false, &b) // 0 92 zstr.ScanAny("ok", &c) // true 93 zstr.ScanAny(1.23, &d) // 1.23 94 ``` 95 96 --- 97 98 # 字符串工具 99 100 ```go 101 // 转为zstr.String类型 102 s := zstr.String("1") 103 ``` 104 105 转为指定类型 106 107 转换失败会返回该类型的零值. 108 支持 `string`, `[]byte`, `bool`, `int`, `int8`, `int16`, `int32`, `int64`, `uint`, `uint8`, `uint16`, `uint32`, `uint64`, `float32`, `float64` 109 110 ```go 111 s.String() // 获取string 112 s.GetBool() // 获取bool 113 s.GetInt() // 获取int 114 s.GetInt32() // 获取int32 115 s.GetUint64() // 获取uint64 116 s.GetFloat32() // 获取float32 117 s.Get... 118 ``` 119 120 转换失败时使用默认值 121 122 ```go 123 s := zstr.String("xxx") 124 s.GetBool(true) // true 125 s.GetInt(1) // 1 126 s.GetInt32(2) // 2 127 s.GetUint64(3) // 3 128 s.GetFloat32(4) // 4 129 s.Get... 130 ``` 131 132 扫描到变量 133 134 支持 `string`, `[]byte`, `bool`, `int`, `int8`, `int16`, `int32`, `int64`, `uint`, `uint8`, `uint16`, `uint32`, `uint64`, `float32`, `float64` 135 136 ```go 137 var a float64 138 var b uint32 139 var c bool 140 var d string 141 _ = s.Scan(&a) 142 _ = s.Scan(&b) 143 _ = s.Scan(&c) 144 _ = s.Scan(&d) 145 ``` 146 147 --- 148 149 # 模板渲染 150 151 将模板数据中的变量替换为指定数据 152 153 ```go 154 func Render(format string, values ...interface{}) string 155 ``` 156 157 `format` 表示模板数据. 示例: `@a @b {@c}` 158 `values` 表示值. 参考[值处理](#值处理) 159 160 161 ## 示例 162 163 ```go 164 zstr.Render("{@a}e", "va") // 按顺序赋值 165 zstr.Render("@a @a e", "va0", "va1") // 按顺序赋值 166 zstr.Render("@a e", map[string]string{"a": "va"}) // 指定变量名赋值 167 zstr.Render("@a @b @c", zstr.KV{"a", "aValue"}, zstr.KV{"b", "bValue"}, zstr.KV{"c", "cValue"}) // 指定变量名赋值 168 zstr.Render("@a @b @c", zstr.KVs{{"a", "aValue"}, {"b", "bValue"}, {"c", "cValue"}}) // 指定变量名赋值 169 zstr.Render("@a @a @a", zstr.KV{"a[0]", "1"}, zstr.KV{"a", "2"}) // 指定变量名下标的优先级比指定变量名更高 170 ``` 171 172 ## 变量名定义 173 174 175 模板变量用 `@` 开头 176 模板变量推荐使用花括号`{}`包起来, 这样能精确的界定模板变量的开头和结尾. 注意花括号内可以有空格. 177 示例: `@a`, `@a_b`, `@A.c`, `{@a....c}`, `{@9}`, `@0...A`, `{ @a }`, `{ @a}`, `{@a }`, `{ @a }` 178 179 180 变量细节参考 [变量](#变量) 181 182 ### 渲染 183 184 模板渲染时遍历找出所有模板变量, 然后替换为匹配的变量值. 185 186 未对变量赋值时, 如果变量被花括号`{}`包裹, 那么会被替换为空字符串, 否则不会替换数据 187 188 比如 `zstr.Render("@a {@b}", zstr.KV{"a", "aValue"})` 未对变量 `b` 进行赋值, 其输出结果为 `aValue `. 189 但是 `zstr.Render("@a @b", zstr.KV{"a", "aValue"})` 输出结果为 `aValue @b`, 因为变量 `b` 没有被花括号`{}`包裹 190 191 --- 192 193 # 值处理 194 195 > 参考源码 [MakeMapOfValues](./values_to_map.go) 196 197 198 支持任何类型的map, 如 `map[string]interface{}`; `map[int]int`; `map[int]string`; `map[string]int` 等. 199 200 可以通过 `zstr.KV` 方式传入. 示例: `zstr.MakeMapOfValues(zstr.KV{"k1", "v1"}, &zstr.KV{"k2", "v2"})`. 201 202 可以通过 `zstr.KVs` 方式传入. 示例: `zstr.MakeMapOfValues(zstr.KVs{{"k1", "v1"}, {"k2", "v2"}})`. 203 204 也可以 `zstr.KV` 和 `zstr.KVs` 混合传入. 示例 `zstr.MakeMapOfValues(zstr.KVs{{"k1", "v1"}}, zstr.KV{"k2", "v2"})`. 205 206 传参时支持顺序传值, 示例 `zstr.MakeMapOfValues("v1", "v2")`, 结果为 `map[string]interface{}{"*[0]": "v1", "*[1]": "v2"}` 207 208 --- 209 210 # 变量 211 212 变量名支持 大小写字母; 数字; 下划线; 小数点; 213 变量名区分大小写; 214 变量开头和结尾不能是小数点, 但是变量中间可以有任意数量的小数点; 215 216 示例: `@a`, `@a_b`, `@A.c`, `{@a....c}`, `{@9}`, `@0...A` 217 218 ## 模板匹配变量名方式 219 220 `key` 可以带下标, 下标从 0 开始, 如: `a[0]` 表示第一次出现的 `a`, `a[5]`表示第 6 次出现的 `a`. 221 星号 `*` 可以匹配任何变量名, 但是必须和下标一起使用, 下标从 0 开始, 如: `*[0]` 表示第 1 个变量, `*[5]` 表示第 6 个变量. 222 223 ## 变量名匹配优先级 224 225 1. 完全匹配变量名+下标 226 2. 完全匹配变量名 227 3. 星号+下标 228 229 如: `a[0]` > `a` > `*[0]` 230 231 232 --- 233 234 # 动态sql 235 236 你是否会有根据不同的条件拼接不同的sql语句的痛苦, 使用 [zstr动态sql](./sql_template.go) 一次根治 237 238 ```go 239 func SqlRender(sqlTemplate string, values ...interface{}) string 240 ``` 241 242 `sqlTemplate` 表示要进行渲染的sql模板数据. 示例: `select * from table where &a (&b |c) {&d like_start}` 243 `values` 表示值. 参考[值处理](#值处理) 244 245 ## 示例 246 247 ```go 248 zstr.SqlRender("select * from table where &a (&b |c)", map[string]interface{}{ 249 "a": 1, 250 "b": 2, 251 "c": 3, 252 }) 253 ``` 254 255 ## 模板语法说明 256 257 语法格式 258 259 `(操作符)(变量名)` 260 `{(操作符)(变量名)}` 261 `{(操作符)(变量名) (标记)}` 262 `{(操作符)(变量名) (标记) (选项)}` 263 `{(操作符)(变量名) (选项)}` 264 265 示例 266 267 `&a` 268 `{&a}` 269 `{&a like}` 270 `{&a like d}` 271 `{&a d}` 272 273 ### 操作符 274 275 `&` 转为 `and 变量名 标记 值`, 一般用于表示一个条件. 276 277 `|` 转为 `or 变量名 标记 值`, 一般用于表示一个条件. 278 279 `#` 转为 `值`. 自带 `attention` 选项. 280 281 `@` 转为 `值`, 一般用于表示一条语句. 自带 `direct` 选项, 且不会为字符串加上引号. `attention` 选项无效 282 283 ### 变量名 284 285 模板变量用一个 [操作符](#操作符) 开头. 286 模板变量推荐使用花括号`{}`包起来, 这样能精确的界定模板变量的开头和结尾, 还可以使用 [标记](#标记) 和 [选项](#选项) 来改变行为. 花括号内允许有空格. 287 示例: `&a`, `|a_b`, `#A.c`, `{&a....c}`, `{@9}`, `@0...A` 288 289 变量细节参考 [变量](#变量) 290 291 ### 标记 292 293 用于改变操作符 `&` 和 `|` 的行为, 默认标记为 = 294 295 `>` 296 `>=` 297 `<` 298 `<=` 299 `!=` 和 `<>` 300 `=` 301 `in` 302 `not_in` 和 `notin` 303 `like` 304 `like_start` 和 `likestart` 305 `like_end` 和 `likeend` 306 307 ### 选项 308 309 + attention, 语法 a, 不会忽略参数值为该类型的零值. 表示该条件必须存在 310 + direct, 语法 d, 直接将值写入sql语句中. 一般用于表示一段语句, 建议别用于表示一个值, 否则可能导致sql注入危险. 311 + must, 语法 m, 必须传值, 否则会panic 312 313 ### 渲染 314 315 **渲染文本之前会缩进文本所有的空格, 所以要渲染的文本一般为单纯的sql语句, 不要将值写在文本中, 而是使用传参的方式, 这是使用sql的标准姿势** 316 317 模板渲染时遍历找出所有模板语法, 然后按语法替换为不同的值. 318 一般情况下如果变量没有传参或为该类型的零值, 则替换为空字符串. 319 如果变量的值为nil, 不同的标志会转为不同的语句. 320 321 --- 322 323 # 模板渲染和动态sql性能说明 324 325 我们写了一个专用函数用于替换正则查找规则, 经过 Benchmark 测试, 速度为正则查找变量方式的 230%. 326 具体的性能可以将代码clone后执行命令 `go test -v -bench .`