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 .`