我是否需要YAML中的字符串引号?

时间:2013-10-01 07:00:47

标签: syntax yaml quotes

我正在尝试编写一个用于Rails项目国际化的YAML字典。我有点困惑,因为在一些文件中,我看到双引号中的字符串,而有些没有。需要考虑几点:

  • example 1 - 所有字符串都使用双引号;
  • example 2 - 没有字符串(最后两个除外)使用引号;
  • YAML cookbook说:用双引号括起字符串允许你使用转义来表示ASCII和Unicode字符。这是否意味着我只有在我想要逃避时才需要使用双引号一些人物?如果是的话 - 为什么他们在第一个例子中到处使用双引号 - 只是为了统一/风格的原因?
  • 示例2的最后两行使用! - 非特定标记,而第一个示例的最后两行不使用 - 它们都有效。

我的问题是:在YAML中使用不同类型的引号有哪些规则?

可以这么说:

  • 一般来说,你不需要引号;
  • 如果你想转义字符,请使用双引号;
  • 使用!单引号,当......?!?

4 个答案:

答案 0 :(得分:441)

在对问题中引用的YAML食谱和一些测试进行简要回顾之后,这是我的解释:

  • 一般情况下,您不需要引号。
  • 使用引号强制字符串,例如如果您的密钥或值为10,但您希望它返回字符串而不是Fixnum,请写'10'"10"
  • 如果您的值包含特殊字符,请使用引号(例如:{}[],&*#?|-<>,{{ 1}},=!%@)。
  • 单引号允许您在字符串中放置几乎任何字符,并且不会尝试解析转义码。 \将作为字符串'\n'返回。
  • 双引号解析转义码。 \n将作为换行符返回。
  • 感叹号引入了一种方法,例如"\n"返回Ruby符号。

对我来说,最好的方法是不使用引号,除非你必须,然后使用单引号,除非你特别想要处理转义码。

更新

“是”和“否”应用引号(单引号或双引号)括起来,否则它们将被解释为TrueClass和FalseClass值:

!ruby/sym

答案 1 :(得分:4)

标记为正确的答案具有极大的误导性。 (虽然解释了野外遇到的yaml)

yaml 中的字符串仅在 (的开头)值可能被误解为数据类型 或值包含“:”(因为它可能被误解为键)时才需要引用。< /p>

例如

foo: '{{ bar }}'

需要引号,因为它可能会被误解为数据类型 dict,但是

foo: barbaz{{ bam }}

不会,因为它不以关键字符开头。接下来,

foo: '123'

需要引号,因为它可能会被误解为数据类型 int,但是

foo: bar1baz234
bar: 123baz

不会,因为它不能被误解为 int

foo: 'yes'

需要引号,因为它可能会被误解为数据类型 bool

foo: "bar:baz:bam"

需要引号,因为值可能会被误解为键。

这些只是示例。使用 yamllint 有助于避免使用错误的标记开始值

foo@bar:/tmp$ yamllint test.yaml 
test.yaml
  3:4       error    syntax error: found character '@' that cannot start any token (syntax)

如果使用 yaml 高效工作,这是必须的。

如某些人所建议的那样引用所有字符串,就像在 python 中使用括号一样。这是一种不好的做法,会损害可读性并抛弃不必引用字符串的美丽特性。在传播虚假知识之前,请阅读文档。

答案 2 :(得分:4)

虽然 Mark 的回答很好地总结了根据 YAML 语言规则何时需要引号,但我认为许多开发人员/管理员在使用 YAML 中的字符串时会问自己“什么应该成为我的处理刺痛的经验法则吗?”

这听起来可能很主观,但是如果您想在真正根据语言规范需要时使用引号,那么您必须记住的规则数量, 对于指定最常见的数据类型之一这样简单的事情来说有点过分。不要误会我的意思,您最终会在定期使用 YAML 时记住它们,但是如果您偶尔使用它,并且您没有开发编写 YAML 的自动化呢?您真的想花时间记住所有规则只是为了正确指定字符串吗?

“经验法则”的全部意义在于节省认知资源并在不假思索的情况下处理常见任务。我们的“CPU”时间可以说比正确处理字符串更有用。

从这个纯粹实用的角度来看,我认为最好的经验法则是单引号字符串。背后的原因:

  • 单引号字符串适用于所有场景,除非您需要使用转义序列。
  • 单引号字符串中唯一需要处理的特殊字符是单引号本身。

这只是一些偶尔使用 YAML 的用户需要记住的 2 条规则,从而最大限度地减少认知工作。

答案 3 :(得分:1)

在使用 Docker Rails 应用程序时,我有这个担忧。

我最喜欢的方法是通常使用引号。这包括使用引号:

  • ${RAILS_ENV}之类的变量
  • 由冒号(:)分隔的值,例如postgres-log:/var/log/postgresql
  • 其他字符串值

但是,我对integer值使用双引号,这些值需要转换为以下字符串:

  • docker-compose版本,例如version: "3.8"
  • 端口号,例如"8080:8080"

但是,对于booleansfloatsintegers之类的特殊情况,以及在其他情况下使用双引号作为输入值的情况,可以解释为strings,请使用双引号。

这里有一个示例docker-compose.yml文件来解释这个概念:

version: "3"

services:
  traefik:
    image: traefik:v2.2.1
    command:
      - --api.insecure=true # Don't do that in production
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

仅此而已。

我希望这会有所帮助