如何在解析 YAML 时从字符串句子中删除撇号/字节标记?

huangapple go评论87阅读模式
英文:

How to remove apostrophe/byte marks from string sentences when trying to parse yaml

问题

示例代码:

import (
	"fmt"
	"log"

	yaml "gopkg.in/yaml.v3"
)

type X struct {
	Example string `yaml:"some-example"`
}

func main() {
	item := X{
		Example: fmt.Sprint("\"some text\""),
	}

	res, err := yaml.Marshal(item)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Print(string(res))
}

打印结果为 some-example: ''"some text"''

想要的结果是 some-example: "some text"

英文:

Live example here

It seems like the yaml parsing library is unable to print "
So when i parse a sentence with ", go adds byte apostrophe around it (')

Is there some trick to just have it print/make simple string/quotation string, without the byte apostrophes added?

Example code:

import (
	"fmt"
	"log"

	yaml "gopkg.in/yaml.v3"
)

type X struct {
	Example string `yaml:"some-example"`
}

func main() {
	item := X{
		Example: fmt.Sprint("\"some text\""),
	}

	res, err := yaml.Marshal(item)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Print(string(res))
}

Prints some-example: '"some text"'

Want some-example: "some text"

答案1

得分: 1

有没有一些技巧可以让它只打印/生成简单的字符串/引号字符串,而不添加字节的撇号?

请注意,您正在打印yaml.Marshal的输出,也就是您正在打印一个有效的YAML文档,而YAML没有任何称为"byte apostrophes"的东西。在YAML中,字符串可以是未引用的双引号引用的单引号引用的,无论如何,它们都是字符串。

# 以下三个都是字符串
a: foo bar
b: "foo bar"
c: 'foo bar'

所以你的原始输出

some-example: '"some text"'

是完全有效的YAML,而不是Go语言添加了单引号,而是gopkg.in/yaml.v3包在做这个。


据我所知,不可能为yaml.Encoder设置一个全局设置,以便将每个字符串都使用双引号样式进行编组,但是您可以使用一个自定义字符串来实现yaml.Marshaler,以便强制yaml.Encoder始终为该自定义类型的任何值输出双引号引用的字符串。

例如:

type DoubleQuotedString string

func (s DoubleQuotedString) MarshalYAML() (interface{}, error) {
	return yaml.Node{
		Kind:  yaml.ScalarNode,
		Style: yaml.DoubleQuotedStyle, // <- 这是相关的部分
		Value: string(s),
	}, nil
}

https://go.dev/play/p/o9VNL5mKdSl

some-example: "\"some text\""
英文:

> Is there some trick to just have it print/make simple string/quotation string, without the byte apostrophes added?

Note that you are printing the output of yaml.Marshal, i.e. you are printing a valid YAML document and YAML does not have anything called "byte apostrophes". In YAML strings can be either unquoted, double quoted, or single quoted, regardless, they are all strings.

# all three are strings 
a: foo bar
b: &quot;foo bar&quot;
c: &#39;foo bar&#39;

So your original output

some-example: &#39;&quot;some text&quot;&#39;

is perfectly valid YAML, and it is not Go that is adding the single quotes, it is the gopkg.in/yaml.v3 package that's doing that.


AFAICT it is not possible to set a global setting for the yaml.Encoder to marshal every string using the double-quoted style, however you can use a custom string that implements yaml.Marshaler to force the yaml.Encoder to always output double quoted strings for any value of that custom type.

For example:

type DoubleQuotedString string

func (s DoubleQuotedString) MarshalYAML() (interface{}, error) {
	return yaml.Node{
		Kind:  yaml.ScalarNode,
		Style: yaml.DoubleQuotedStyle, // &lt;- this is the relevant part
		Value: string(s),
	}, nil
}

https://go.dev/play/p/o9VNL5mKdSl

some-example: &quot;\&quot;some text\&quot;&quot;

答案2

得分: 0

相同的问题,使用%+v打印结构体字段时不显示单引号,但在使用gopkg.in/yaml.v3包的编组过程中,单引号被添加了。结果是我的YAML文件(显然是有效的)看起来很奇怪。

  k8s_labels:
  - '&#39;&quot;nic-type-sriov=false&quot;&#39;'
英文:

Same issue, Printing out the field of struct with %+v does not show single quotes but somehow during the marshaling process using the gopkg.in/yaml.v3 package, single quote is being added. As a result my yaml(apparently, even though is valid) looks odd

  k8s_labels:
  - &#39;&quot;nic-type-sriov=false&quot;&#39;

huangapple
  • 本文由 发表于 2022年12月1日 23:04:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/74644014.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定