从https://en.wikipedia.org/wiki/UTF-8#Invalid_code_points开始,我知道U + D800到U + DFFF无效。所以在十进制系统中,它是55296到57343。
最大有效Unicode是' \ U0010FFFF'。在十进制系统中,它是1114111
我的代码:
package main
import "fmt"
import "unicode/utf8"
func main() {
fmt.Println("Case 1(Invalid Range)")
str := fmt.Sprintf("%c", rune(55296+1))
if !utf8.ValidString(str) {
fmt.Print(str, " is not a valid Unicode")
} else {
fmt.Println(str, " is valid unicode character")
}
fmt.Println("Case 2(More than maximum valid range)")
str = fmt.Sprintf("%c", rune(1114111+1))
if !utf8.ValidString(str) {
fmt.Print(str, " is not a valid Unicode")
} else {
fmt.Println(str, " is valid unicode character")
}
}
为什么ValidString函数没有为输入的无效unicode字符返回false?我确信我的理解是错的,有人可以解释一下吗?
答案 0 :(得分:3)
您的问题发生在Sprintf中。因为你给它一个无效字符Sprintf替换为rune(65533)
,这是使用的unicode替换字符而不是无效字符。所以你的字符串是有效的UTF8。
如果您执行以下操作,也会发生这种情况:str := string([]rune{ 55297 })
所以这可能是创建符文时发生的事情。从https://blog.golang.org/strings
如果你想强制你的字符串包含无效的UTF8,你可以像这样编写第一个字符串:
str := string([]byte{237, 159, 193})
答案 1 :(得分:2)
您使用无效值并使用Sprintf进行转换。它被转换为错误值。然后检查错误值,这是一个有效的Unicode代码点。
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
fmt.Println("Case 1: Invalid Range")
str := fmt.Sprintf("%c", rune(55296+1))
fmt.Printf("%q %X %d %d\n", str, str, []rune(str)[0], utf8.RuneError)
if !utf8.ValidString(str) {
fmt.Print(str, " is not a valid Unicode")
} else {
fmt.Println(str, " is valid unicode character")
}
fmt.Println("Case 2: More than maximum valid range")
str = fmt.Sprintf("%c", rune(1114111+1))
fmt.Printf("%q %X %d %d\n", str, str, []rune(str)[0], utf8.RuneError)
if !utf8.ValidString(str) {
fmt.Print(str, " is not a valid Unicode")
} else {
fmt.Println(str, " is valid unicode character")
}
}
输出:
Case 1: Invalid Range
"�" EFBFBD 65533 65533
� is valid unicode character
Case 2: More than maximum valid range
"�" EFBFBD 65533 65533
� is valid unicode character