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

Ale*_*pov 349 syntax quotes yaml

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

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

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

可以这么说:

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

Mar*_*rry 492

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

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

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

更新

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

en:
  yesno:
    'yes': 'Yes'
    'no': 'No'
Run Code Online (Sandbox Code Playgroud)

  • 鉴于所有这些警告,我宁愿在任何地方使用引号: - / (43认同)
  • YAML中字符串的规则非常复杂,因为有许多不同类型的字符串.我在这里写了一张桌子:http://stackoverflow.com/questions/3790454/in-yaml-how-do-i-break-a-string-over-multiple-lines/21699210#21699210 (27认同)
  • 我并没有试图提供完整的图片,只是一些经验法则.是的,看起来有时,一些特殊字符(保留指示符)可以在没有引号的情况下使用(只要保留指示符不能启动普通标量),但是只要看到特殊字符就使用引号并没有错. (17认同)
  • 这不完整.例如,`@`和\`可以在普通字符串中的任何地方使用,除了在开头,因为它们是[保留指标](http://yaml.org/spec/1.2/spec.html#id2774228). (9认同)
  • 此外,这是我写的一个非常完整的参考:http://blogs.perl.org/users/tinita/2018/03/strings-in-yaml---to-quote-or-not-to-quote.html (3认同)
  • 只是一些额外的信息:如果您的文档在yaml 1.2中包含指令结束标记行(`---`),则可以使用`%`开始标量 (2认同)
  • “如果您的值包含特殊字符,请使用引号”——这是一个严重的过度简化,请参阅这篇优秀的博客文章,了解何时需要引号:http://blogs.perl.org/users/tinita/2018/03/strings- in-yaml---引用或不引用.html (2认同)
  • 另引用挪威 https://hitchdev.com/strictyaml/why/implicit-typing-removed/ (2认同)

F1k*_*1ko 75

这个问题有一些很好的答案。\n但是,我想扩展它们并提供新的官方 YAML v1.2.2 规范(2021 年 10 月 1 日发布)的一些上下文,这是考虑 YAML 的所有事物的“真正来源” 。

\n

可以使用三种不同的样式来表示字符串,每种样式都有自己的(缺点)优点:

\n
\n

YAML 提供三种流标量样式:双引号、单引号和普通(不带引号)。每一种都在可读性和表达能力之间提供了不同的权衡。

\n
\n

双引号样式

\n
\n
    \n
  • 双引号样式由周围的"指示符指定。这是唯一能够通过使用\\转义序列来表达任意字符串的样式。这是以必须转义\\"字符为代价的。
  • \n
\n
\n

单引号样式

\n
\n
    \n
  • 单引号样式由周围的\'指示符指定。因此,在单引号标量内,需要重复此类字符。这是在单引号标量中执行的唯一转义形式。特别是,\\"字符可以自由使用。这将单引号标量限制为可打印字符。此外,只能在空格字符被非空格包围的长单引号行中打断。
  • \n
\n
\n

普通(不带引号)样式

\n
\n
    \n
  • 普通(未引用)样式没有识别指示符,并且不提供任何形式的转义。因此,它是最具可读性、最受限制且对上下文最敏感的风格。除了受限制的字符集之外,普通标量不能为空或包含前导或尾随空白字符。只能在空格字符被非空格包围的长普通行中打断。\n普通标量不得以大多数指示符开头,因为这会导致与其他 YAML 构造产生歧义。但是,如果:,?-指示符后跟非空格 \xe2\x80\x9csafe\xe2\x80\x9d 字符,则可以将 , 和 指示符用作第一个字符,因为这不会导致歧义。
  • \n
\n
\n

长话短说

\n

话虽如此,根据官方 YAML 规范,应该

\n
    \n
  • 只要适用,请使用不带引号的样式,因为它是最具可读性的。
  • \n
  • 如果字符串内使用\'诸如"和 之类的字符,请使用单引号样式 ( ) 以避免转义它们,从而提高可读性。\\
  • \n
  • "当前两个选项不够时,即需要更复杂的换行符或需要不可打印字符的情况下,请使用双引号样式 ( )。
  • \n
\n

  • 一些额外的警告: * 普通标量绝不能包含 `: ` 和 ` #` 字符组合。此外,在流集合内部或用作隐式键时,普通标量不得包含 `[`、`]`、`{`、`}` 和 `,` 字符。* (2认同)

小智 24

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

例如

foo: '{{ bar }}'
Run Code Online (Sandbox Code Playgroud)

需要引号,因为它可能会被误解为 datatype dict,但是

foo: barbaz{{ bam }}
Run Code Online (Sandbox Code Playgroud)

不是,因为它不以关键 char 开头。下一个,

foo: '123'
Run Code Online (Sandbox Code Playgroud)

需要引号,因为它可能会被误解为 datatype int,但是

foo: bar1baz234
bar: 123baz
Run Code Online (Sandbox Code Playgroud)

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

foo: 'yes'
Run Code Online (Sandbox Code Playgroud)

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

foo: "bar:baz:bam"
Run Code Online (Sandbox Code Playgroud)

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

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

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

如果要高效地使用 yaml,那么这是必须的。

正如一些人建议的那样引用所有字符串,就像在 python 中使用括号一样。这是不好的做法,会损害可读性并放弃不必引用字符串的美丽功能。

  • 感谢您提供的示例。看来我们同意;正如我在回答中所说:“最好的方法是除非必要,否则不要使用引号。” 关于您有用的数据类型规则的问题:您是否像OP的问题中那样专门指Ruby on Rails中的YAML?似乎数据类型解释可能因编程语言而异。 (2认同)

wom*_*ire 9

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

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

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

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

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

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

  • 更简单的一种是:对字符串使用双引号。 (6认同)
  • @acmoune我不确定双引号是否是最好的*默认*选项,因为它们对转义序列的自动解释可能不是您所期望的。不过,如果你总是记得它,并且如果你特别需要它,那么是的,为什么不呢? (4认同)