gpt4 book ai didi

unicode - 在 Go 中输出不带引号的 Unicode

转载 作者:IT王子 更新时间:2023-10-29 01:13:58 27 4
gpt4 key购买 nike

我正在使用 goyaml 作为 YAML 美化器。通过加载和转储 YAML 文件,我可以对其进行源代码格式化。我将 YAML 源文件中的数据解码为结构,编码这些字节,然后将字节写入输出文件。但是这个过程将我的 Unicode 字符串变成了引用字符串的文字版本,我不知道如何反转它。

示例输入 subtitle.yaml:

line: 你好

我已将所有内容精简到最小的可重现问题。这是代码,使用 _ 来捕获不会弹出的错误:

package main                                                                                                                                                                                      

import (
"io/ioutil"
//"unicode/utf8"
//"fmt"

"gopkg.in/yaml.v1"
)

type Subtitle struct {
Line string
}

func main() {
filename := "subtitle.yaml"
in, _ := ioutil.ReadFile(filename)
var subtitle Subtitle
_ = goyaml.Unmarshal(in, &subtitle)
out, _ := goyaml.Marshal(&subtitle)

//for len(out) > 0 { // For debugging, see what the runes are
// r, size := utf8.DecodeRune(out)
// fmt.Printf("%c ", r)
// out = out[size:]
//}

_ = ioutil.WriteFile(filename, out, 0644)
}

实际输出subtitle.yaml:

line: "\u4F60\u597D"

我想在获取变量 out 后反转 goyaml 中的怪异现象。

注释掉的 rune 打印代码块,为了清晰起见在 rune 之间添加了空格,输出如下。它表明像 这样的 Unicode rune 没有被解码,而是按字面意思处理:

l i n e :   " \ u 4 F 6 0 \ u 5 9 7 D "

在将 out 写入输出文件之前,如何取消引用,使输出看起来像输入(尽管经过美化)?

期望的输出subtitle.yaml:

line: "你好"

临时解决方案

我已经提交了 https://github.com/go-yaml/yaml/issues/11 .与此同时,@bobince 关于 yaml_emitter_set_unicode 的提示有助于解决问题。它被定义为 C 绑定(bind)但从未调用(或提供设置它的选项)!我更改了 encode.go 并添加了 yaml_emitter_set_unicode(&e.emitter, true) to line 20 ,一切都按预期工作。将其设为可选会更好,但这需要更改 Marshal API。

最佳答案

有一个类似的问题,可以应用它来规避 goyaml.Marshal() 中的错误。 (*Regexp) ReplaceAllFunc 是你的 friend ,你可以用它来扩展字节数组中的转义 Unicode rune 。对于生产来说可能有点太脏了,但可以用于示例 ;-)

package main                                                                                                                                                                                      

import (
"io/ioutil"
"unicode/utf8"
"regexp"
"strconv"
"launchpad.net/goyaml"
)

type Subtitle struct {
Line string
}

var reFind = regexp.MustCompile(`^\s*[^\s\:]+\:\s*".*\\u.*"\s*$`)
var reFindU = regexp.MustCompile(`\\u[0-9a-fA-F]{4}`)

func expandUnicodeInYamlLine(line []byte) []byte {
// TODO: restrict this to the quoted string value
return reFindU.ReplaceAllFunc(line, expandUnicodeRune)
}

func expandUnicodeRune(esc []byte) []byte {
ri, _:= strconv.ParseInt(string(esc[2:]), 16, 32)
r := rune(ri)
repr := make([]byte, utf8.RuneLen(r))
utf8.EncodeRune(repr, r)
return repr
}

func main() {
filename := "subtitle.yaml"
filenameOut := "subtitleout.yaml"
in, _ := ioutil.ReadFile(filename)
var subtitle Subtitle
_ = goyaml.Unmarshal(in, &subtitle)
out, _ := goyaml.Marshal(&subtitle)

out = reFind.ReplaceAllFunc(out, expandUnicodeInYamlLine)
_ = ioutil.WriteFile(filenameOut, out, 0644)
}

关于unicode - 在 Go 中输出不带引号的 Unicode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21696845/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com