假设我有一个这样的文本文件。
u0053
u0075
u006E
有没有办法把它转换成这个?
S
u
n
目前,我使用ioutil.ReadFile("data.txt")
,但当我打印数据时,我得到的是unicode代码点,而不是字符串文字。我意识到这是ReadFile
的正确行为,只是我不想要。
我的目标是用它们的文字字符替换代码点。
您可以使用strconv.Unquote()
和strconv.UnquoteChar()
函数进行转换。
您应该注意的一件事是,strconv.Unquote()
只能取消引号中的字符串的引号(例如,以引号字符"
或后引号字符`
开头和结尾),因此我们必须手动附加它。
参见此示例:
lines := []string{
`u0053`,
`u0075`,
`u006E`,
}
fmt.Println(lines)
for i, v := range lines {
var err error
lines[i], err = strconv.Unquote(`"` + v + `"`)
if err != nil {
fmt.Println(err)
}
}
fmt.Println(lines)
fmt.Println(strconv.Unquote(`"Gou0070x68x65x72"`))
输出(在Go Playground上尝试):
[u0053 u0075 u006E]
[S u n]
Gopher <nil>
如果要取消引用的字符串包含单个rune
的转义序列(或者只想取消引用第一个rune
),则可以使用strconv.UnquoteChar()
。这就是它的样子(注意:在这种情况下不需要引用输入,就像strconv.Unquote()
一样):
runes := []string{
`u0053`,
`u0075`,
`u006E`,
}
fmt.Println(runes)
for _, v := range runes {
var err error
value, _, _, err := strconv.UnquoteChar(v, 0)
if err != nil {
fmt.Println(err)
}
fmt.Printf("%cn", value)
}
这将输出(在Go Playground上尝试):
[u0053 u0075 u006E]
S
u
n
一种稍微不同的方法是使用strconv.ParseInt
,这会生成更少的垃圾,并使用更少的内部逻辑(Unquote
会进行许多其他检查)来解析行:
for i, v := range lines {
if len(v) != 6 {
continue
}
if r, err := strconv.ParseInt(v[2:], 16, 32); err == nil {
lines[i] = string(r)
}
}
操场
您可以使用这个:
import "github.com/chzyer/readline/runes"
// unicodeUnquote converts unicode points such as u0053 to UTF8 encoding.
func unicodeUnquote(bs []byte) []byte {
unicodeEscapeRx := regexp.MustCompile(`\u[0-9a-fA-F]{4}`)
return unicodeEscapeRx.ReplaceAllFunc(bs, func(code []byte) []byte {
rune, _, _, _ := strconv.UnquoteChar(string(code), 0)
width := runes.Width(rune)
runeBytes := make([]byte, width)
utf8.EncodeRune(runeBytes, rune)
return runeBytes
})
}
完整的示例位于https://go.dev/play/p/ElIGZvJNyEF.