0

在下面的代码中:

package main

import "fmt"

func main() {
    s := []rune{'\u0041', '\u0042', '\u0043', '\u20AC', -1}
    fmt.Println(s)
    fmt.Println(string(s)) // ABC€�
    fmt.Println(s[3] == '€')
    fmt.Println(s[4] == '�')
    fmt.Println(s[4] == '\uFFFD')
}

输入流具有无效的 unicode 代码点 -1,存储为\uFFFD.

但下面的行给出的输出为false

    fmt.Println(s[4] == '�')
    fmt.Println(s[4] == '\uFFFD')

如何验证有效 unicode 代码点范围之外的 unicode 代码点值?

4

1 回答 1

2

尝试这个:

slice1 := []rune{'\u0041', '\u0042', '\u0043', '\u20AC', -1}
st := string(slice1)
slice2 := []rune(st)
fmt.Println(slice2[4] == '\uFFFD') // true

由于s[4]-1结果s[4] == '\uFFFD'是错误的。
'\uFFFD'ReplacementChar代表无效代码点的 。
并且是无效代码点的替换,例如-1,使用string([]rune{'A', -1})替换-1'\uFFFD',试试这个

package main

import (
    "fmt"
    "unicode"
    "unicode/utf8"
)

func main() {
    fmt.Println(unicode.ReplacementChar)
    fmt.Println(utf8.ValidRune(unicode.ReplacementChar))

    rs := []rune{'A', -1}
    s := string(rs)
    fmt.Println(s)
    fmt.Println([]rune(s)) //[65 65533]
}

有效符文

func ValidRune(r rune) bool

ValidRune 报告 r 是否可以合法地编码为 UTF-8。超出范围或代理一半的代码点是非法的。

const (
    surrogateMin = 0xD800
    surrogateMax = 0xDFFF
    MaxRune   = '\U0010FFFF' // Maximum valid Unicode code point.
)
// ValidRune reports whether r can be legally encoded as UTF-8.
// Code points that are out of range or a surrogate half are illegal.
func ValidRune(r rune) bool {
    switch {
    case 0 <= r && r < surrogateMin:
        return true
    case surrogateMax < r && r <= MaxRune:
        return true
    }
    return false
}

例子:

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {
    slice := []rune{'\u0041', '\u0042', '\u0043', '\u20AC', '\uFFFD', 0xfffffff, -1}
    for i, v := range slice {
        fmt.Printf("%d %q %v\n", i, v, utf8.ValidRune(v))
    }
}

输出:

0 'A' true
1 'B' true
2 'C' true
3 '€' true
4 '�' true
5 %!q(int32=268435455) false
6 %!q(int32=-1) false

请参阅:
为什么我的字符串返回 "\ufffd\ufffdN am e"

https://github.com/golang/go/issues/21975

于 2020-11-01T04:48:05.550 回答