【问题标题】:How to verify the invalid unicode code point value?如何验证无效的 unicode 代码点值?
【发布时间】:2020-11-01 03:48:13
【问题描述】:

在下面的代码中:

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码点值?

【问题讨论】:

    标签: go


    【解决方案1】:

    试试这个:

    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',试试this

    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]
    }
    

    ValidRune

    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
    

    见:
    Why is my String returning "\ufffd\ufffdN a m e"

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-18
      • 2021-12-15
      • 2011-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-22
      相关资源
      最近更新 更多