unicode/utf8.FullRune în Go

FullRune verifică dacă octeții încep cu un caracter UTF-8 complet; RuneStart dacă un octet poate fi începutul unui caracter.

Sintaxă
func FullRune(p []byte) bool
func FullRuneInString(s string) bool
func RuneStart(b byte) bool

Ce face unicode/utf8.FullRune

Când citești date în bucăți (din rețea sau dintr-un fișier), un caracter de mai mulți octeți poate fi rupt între două bucăți. utf8.FullRune(p) spune dacă p începe cu un caracter complet; dacă nu, trebuie să mai aștepți octeți. FullRuneInString face la fel pentru un string. Un octet invalid este considerat „complet”, pentru că va fi decodat ca RuneError.

utf8.RuneStart(b) spune dacă octetul b poate fi primul octet al unui caracter. Octeții de continuare (de forma 10xxxxxx) nu pot. Cu ea poți tăia un text la o lungime maximă în octeți fără să rupi o literă.

Parametri

Parametru Descriere
p / s Octeții sau textul verificat.
b La RuneStart: octetul verificat.

Ce returnează

true sau false.

Exemple

Exemplul 1: Caracter întreg sau rupt

„ș” se scrie în UTF-8 cu octeții c8 99. Doar primul octet nu este un caracter complet.

package main

import (
	"fmt"
	"unicode/utf8"
)

func main() {
	s := []byte("ș")
	fmt.Printf("octeți: % x\n", s)
	fmt.Println(utf8.FullRune(s[:1]), utf8.FullRune(s))
	fmt.Println(utf8.FullRuneInString("€"[:2]), utf8.FullRuneInString("€"))
	fmt.Println(utf8.RuneStart(s[0]), utf8.RuneStart(s[1]))
}

Rezultat

octeți: c8 99
false true
false true
true false

Exemplul 2: Tăiere la maxim n octeți fără litere rupte

Dacă poziția de tăiere cade în mijlocul unui caracter, ne mutăm înapoi până la un octet de început.

package main

import (
	"fmt"
	"unicode/utf8"
)

func taieOcteti(s string, max int) string {
	if len(s) <= max {
		return s
	}
	for max > 0 && !utf8.RuneStart(s[max]) {
		max--
	}
	return s[:max]
}

func main() {
	s := "Iași și Brașov"
	for _, n := range []int{3, 4, 9, 100} {
		t := taieOcteti(s, n)
		fmt.Printf("max %3d -> %q (%d octeți, valid: %t)\n", n, t, len(t), utf8.ValidString(t))
	}
}

Rezultat

max   3 -> "Ia" (2 octeți, valid: true)
max   4 -> "Iaș" (4 octeți, valid: true)
max   9 -> "Iași și" (9 octeți, valid: true)
max 100 -> "Iași și Brașov" (17 octeți, valid: true)

Greșeli frecvente

  • Decodezi fiecare bucată citită din rețea separat: un caracter rupt între două bucăți devine două �. Verifică cu FullRune și păstrează octeții rămași pentru bucata următoare (sau folosește bufio.Reader.ReadRune).

Comenzi înrudite