Skip to main content

YAML 本身的转义

一个比较好的答案: How do I break a string in YAML over multiple lines? 我们这里只针对性的讨论一下 ', ", \ 和转义字符比如 \n, \r 推荐的 yaml string 格式用 “, ", | 这 3 种形式。
  • | 或者 |- 是不需要考虑 yaml 转义的格式,类似 golang 中的 `
    1. 会保留结尾空格
    2. 会保留换行
    3. 不支持转义
    4. | 会保留最后的换行, |- 不会
  • " 是支持转义字符的格式
    1. 换行会变成空格, 如果想不变成空格,需要结尾加 \
    2. 2连换行会变成换行, \n 会变成换行
    3. 支持转义, " 需要转义
  • “ 是不支持转义的,且不支持 yaml 的一些保留字符的比如:#, :
    1. 开头不能是 ', "
    2. 不得占用 yaml 的关键字符
    3. 不支持转义
注: 遇事不决 hex dump 一下,各种语言的字符串变量通常还有自己的转义, print 打印出来的字符可能还会被 shell 本身处理,会让事情变得更加复杂 举一些常见的例子:
  • 如果不用换行,不用转义, 建议 “
  • 如果希望换行格式好看一些,且也不用转义的话,建议使用 | 或者 |-
  • 如果涉及到转义的话,可以使用 "
注: 这里解决之前一个遗留的问题: multipart/form-data 可以参考 apache-flink-upload-rce.yml 这个 yaml 文件, 其中需要发送 multipart/form-data 的包。它的每一行是要以 \r\n(hex 0d 0a) 结尾的。 一个错误的写法:(可以关注其中的 0a)
我们可以用 " 来表示此包。需要做的事情是:
  1. 转义掉其中的 "
  2. 正确的处理换行:
    1. 换行会变成空格, 如果想不变成空格,需要结尾加 \
    2. 2连换行会变成换行, \n 会变成换行
推荐的写法:
PS:也可以写在一行,就是比较难读 PSS: 要是愿意的话,也可以用 2 连换行来表示 \n 不过也有点难看就是了 -_-

CEL 本身的转义

cel 转义 这里就不赘述 cel 本身的转义了,主要讨论几个在 yaml 中写 cel 的情况。最简单的方式就是 yaml 采用不需要转义的方式 “ 或者 |
  • cel 也不需要转义
  • yaml 不转义, CEL 转义

正则的转义(RE)

CEL 支持输入正则,来使用 match 方法等,不幸的是正则也需要转义。推荐:
  1. yaml 采用不需要转义的方式 “ 或者 |
  2. cel 也采用不需要转义的方式 r' 或者 r"
一些例子:
  • 正则不转义
  • 正则转义
一个复杂的例子:
思路讲解:
  1. 考虑正则应该如何写, 该例子需要转义 [product:\['c="a"'\]
  2. 考虑 cel 转义, 因为含有 ' ", 所以必须要转义, 选择 " 的方式,需要转义 "\
    1. 首先转义 \: product:\\['c="a"'\\]
    2. 然后转义 ": product:\\['c=\"a\"'\\]
    3. 最后用双引包裹: "product:\\['c=\"a\"'\\]".matches(a)
  3. 考虑 yaml 转义,选择 | 不需要转义, 最终:"product:\\['c=\"a\"'\\]".matches(a)
PS(大脑升级): 就要 yaml 用 " 格式,那么会是什么样子的呢?
  1. 考虑正则应该如何写, 该例子需要转义 [product:\['c="a"'\]
  2. 考虑 cel 转义, 因为含有 ' ", 所以必须要转义, 选择 " 的方式,需要转义 "\
    1. 首先转义 \: product:\\['c="a"'\\]
    2. 然后转义 ": product:\\['c=\"a\"'\\]
    3. 最后用双引包裹: "product:\\['c=\"a\"'\\]".matches(a)
  3. 考虑 yaml 转义,需要转义 \, "
    1. 首先转义 \: "product:\\\\['c=\\"a\\"'\\\\]".matches(a)
    2. 其次转义 ": \"product:\\\\['c=\\\"a\\\"'\\\\]\".matches(a)
    3. 最后用 " 包裹: "\"product:\\\\['c=\\\"a\\\"'\\\\]\".matches(a)"