string: |
  *string* 类型表示不可变的字节序列。Lua 使用 8 位编码：字符串可以包含任意 8 位值，
  包括嵌入的零（`\0`）。Lua 也与编码无关；它不会对字符串的内容做任何假设。

string.byte: |
  返回字符 `s[i]`、`s[i+1]`、...、`s[j]` 的内部数值码。`i` 的默认值为 1，`j` 的默认值为 `i`。
  这些索引会按 `string.sub` 的相同规则进行修正。

  注意：这些数值码并不一定能跨平台移植。

string.char: |
  接收零个或多个整数。返回一个长度等于参数个数的字符串，其中每个字符的内部数值码
  等于其对应的参数。

  注意：这些数值码并不一定能跨平台移植。

string.dump: |
  返回一个字符串，包含给定函数的二进制表示（*二进制块*）。之后对该字符串调用 `load`，
  会得到该函数的一个副本（但其上值是新的实例）。如果 `strip` 为真，则为了节省空间，
  二进制表示可能不会包含该函数的全部调试信息。

  对于带上值的函数，只会保存上值的数量；（重新）加载后，这些上值会变成包含 **nil**
  的新实例。（你可以使用 debug 库按需序列化并恢复函数的上值。）

string.find: |
  在字符串 `s` 中查找 `pattern` 的第一次匹配。如果找到，则返回该匹配在 `s` 中的起始与结束索引；
  否则返回 **nil**。

  可选的第三个数字参数 `init` 指定从哪里开始搜索；默认值为 1，也可以为负数。
  可选的第四个参数 `plain` 为 **true** 时，会关闭模式匹配机制：函数将进行普通的“查找子串”操作，
  此时 `pattern` 中不会有任何字符被视为具有特殊含义的“魔法字符”。注意：如果提供了 `plain`，则也必须提供 `init`。

  如果 `pattern` 含有捕获，则匹配成功时也会在两个索引之后返回捕获到的值。

string.format: |
  按第一个参数（必须是字符串）中的描述，对后续可变数量的参数进行格式化，并返回格式化后的字符串。
  格式字符串遵循 ISO C 的 `sprintf` 的规则，区别在于：不支持选项/修饰符 `*`、`h`、`L`、`l`、`n`、`p`，
  且额外支持一个 `q` 选项。

  `q` 选项会以“可被 Lua 源码当作常量读回”的形式格式化布尔值、nil、数字和字符串：
  布尔值与 nil 会直接写作 `true`、`false`、`nil`；浮点数会用十六进制表示以保留全部精度；
  字符串会放在双引号中，并在必要时使用转义序列以确保 Lua 解释器可以安全读回。

  例如：
  ```lua
  string.format('%q', 'a string with "quotes" and \n new line')
  ```
  可能产生：
  ```lua
  "a string with \"quotes\" and \n new line"
  ```

  选项 `A`、`a`、`E`、`e`、`f`、`g`、`G` 和 `g` 需要一个数字参数。
  选项 `c`、`d`、`i`、`o`、`u`、`X`、`x` 需要一个整数参数。
  当 Lua 使用 C89 编译器编译时，选项 `A` 和 `a`（十六进制浮点数）不支持任何修饰符（标志、宽度、长度）。

  选项 `s` 需要一个字符串；若参数不是字符串，则按与 `tostring` 相同的规则转换为字符串。
  如果 `s` 选项带有任何修饰符（标志、宽度、长度），则字符串参数不应包含嵌入的零字节。

string.gmatch@@1: |
  返回一个迭代器函数：每次调用时，它都会在字符串 `s` 上返回 `pattern` 的下一组捕获结果。
  若 `pattern` 未指定捕获，则每次返回整个匹配内容。

  例如，下面的循环会遍历字符串 `s` 中的所有单词，并逐行打印：

  ```lua
  s = "hello world from Lua"
  for w in string.gmatch(s, "%a+") do
      print(w)
  end
  ```

  下一个示例把给定字符串中的所有 `key=value` 对收集到表中：

  ```lua
  t = {}
  s = "from=world, to=Lua"
  for k, v in string.gmatch(s, "(%w+)=(%w+)") do
      t[k] = v
  end
  ```

  注意：对该函数而言，模式开头的插入符 '`^`' 不会作为锚点使用，因为那会阻止迭代。

string.gmatch@>5.4: |
  返回一个迭代器函数：每次调用时，它都会在字符串 `s` 上返回 `pattern` 的下一组捕获结果。
  若 `pattern` 未指定捕获，则每次返回整个匹配内容。 第三个可选参数 `init` 指定从哪里开始搜索；
  默认值为 1，也可以为负数。

  例如，下面的循环会遍历字符串 `s` 中的所有单词，并逐行打印：

  ```lua
  s = "hello world from Lua"
  for w in string.gmatch(s, "%a+") do
      print(w)
  end
  ```

  下一个示例把给定字符串中的所有 `key=value` 对收集到表中：

  ```lua
  t = {}
  s = "from=world, to=Lua"
  for k, v in string.gmatch(s, "(%w+)=(%w+)") do
      t[k] = v
  end
  ```

  注意：对该函数而言，模式开头的插入符 '`^`' 不会作为锚点使用，因为那会阻止迭代。

string.gsub: |
  返回 `s` 的一个副本，其中所有（或前 `n` 个，如果给出）匹配 `pattern` 的内容都会被 `repl` 替换。
  `repl` 可以是字符串、表或函数。`gsub` 还会把发生的匹配总数作为第二个返回值返回。

  若 `repl` 为字符串，则直接用该字符串替换。此时字符 `%` 用作转义：`repl` 中形如 `%n`（*n* 为 1~9）
  的序列表示第 *n* 个捕获子串；`%0` 表示整个匹配；`%%` 表示单个 `%`。

  若 `repl` 为表，则每次匹配都会用“第一个捕获”作为键查询该表；如果 `pattern` 没有捕获，则用整个匹配作为键。

  若 `repl` 为函数，则每次匹配都会调用该函数，并按顺序把所有捕获子串作为参数传入；如果没有捕获，则把整个匹配作为唯一参数传入。

  若表查询或函数调用的返回值是字符串或数字，则用它作为替换内容；否则，如果返回 false 或 nil，则表示不替换（即保留原始匹配）。

  # 示例：
  ```lua
  x = string.gsub("hello world", "(%w+)", "%1 %1")
  -- > x="hello hello world world"
  x = string.gsub("hello world", "%w+", "%0 %0", 1)
  -- > x="hello hello world"
  x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
  -- > x="world hello Lua from"
  x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
  -- > x="home = /home/roberto, user = roberto"
  x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
      return loadstring(s)()
  end)
  -- > x="4+5 = 9"
  local t = {name="lua", version="5.3"}
  x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
  -- > x="lua-5.3.tar.gz"
  ```

string.len: |
  接收一个字符串并返回其长度。空字符串 `""` 的长度为 0。
  嵌入的零字节也会计入长度，因此 `"a\000bc\000"` 的长度为 5。

string.lower: |
  接收一个字符串并返回该字符串的副本，将其中所有大写字母转换为小写；其余字符保持不变。
  什么算作大写字母取决于当前的区域设置。

string.match: |
  在字符串 `s` 中查找 `pattern` 的第一次*匹配*。如果匹配成功，则返回模式中的捕获；否则返回 **nil**。
  如果 `pattern` 没有捕获，则返回整个匹配内容。可选的第三个数字参数 `init` 指定从哪里开始搜索；默认值为 1，可为负数。

string.pack: |
  按格式字符串 `fmt` 将 `v1`、`v2` 等值打包（即以二进制形式序列化），并返回得到的二进制字符串。

string.packsize: |
  返回使用给定格式调用 `string.pack` 时生成的字符串大小。
  格式字符串不能包含变长选项 '`s`' 或 '`z`'。

string.rep: |
  返回 `n` 个以字符串 `sep` 为分割符连在一起的字符串。
  默认的 `sep` 值为空字符串（即没有分割符）。如果 `n` 不是正数则返回空串。

  请注意，单次调用此函数极易耗尽机器的内存。

string.reverse: |
  返回将字符串 `s` 反转后的新字符串。

string.sub: |
  返回 `s` 的子串：从 `i` 开始直到 `j` 结束（包含两端）。`i` 与 `j` 均可为负数。
  若省略 `j`，则默认为 -1（等同于字符串长度）。

  特别地，`string.sub(s, 1, j)` 返回 `s` 的一个前缀，其长度为 `j`；
  `string.sub(s, -i)`（`i` 为正）返回 `s` 的一个后缀，其长度为 `i`。

  将负索引换算后，若 `i` 小于 1，则修正为 1；若 `j` 大于字符串长度，则修正为该长度。
  若修正后 `i` 大于 `j`，则返回空字符串。

string.unpack: |
  按格式字符串 `fmt` 从字符串 `s` 中解包并返回其中的值。
  可选参数 `pos` 指定从 `s` 的哪个位置开始读取（默认值为 1）。
  除了解包得到的值之外，本函数还会返回 `s` 中第一个未读字节的索引。

string.upper: |
  接收一个字符串并返回该字符串的副本，将其中所有小写字母转换为大写；其余字符保持不变。
  什么算作小写字母取决于当前的区域设置。

