Puoi provare RuneCountInString
dal pacchetto utf8.
restituisce il numero di rune in p
che, come illustrato in questa sceneggiatura : la lunghezza di "Mondo" potrebbe essere 6 (quando scritto in cinese: "世界"), ma il suo conteggio delle rune è 2:
package main
import "fmt"
import "unicode/utf8"
func main() {
fmt.Println("Hello, 世界", len("世界"), utf8.RuneCountInString("世界"))
}
Phrozen aggiunge nei commenti :
In realtà puoi fare len()
rune semplicemente digitando il casting.
len([]rune("世界"))
stamperà 2
. Alle partite in Go 1.3.
E con CL 108985 (maggio 2018, per Go 1.11), len([]rune(string))
è ora ottimizzato. (Risolve il problema 24923 )
Il compilatore rileva len([]rune(string))
automaticamente il pattern e lo sostituisce con for r: = range s call.
Aggiunge una nuova funzione di runtime per contare le rune in una stringa. Modifica il compilatore per rilevare il modello len([]rune(string))
e lo sostituisce con la nuova funzione di runtime di conteggio delle rune.
RuneCount/lenruneslice/ASCII 27.8ns ± 2% 14.5ns ± 3% -47.70% (p=0.000 n=10+10)
RuneCount/lenruneslice/Japanese 126ns ± 2% 60ns ± 2% -52.03% (p=0.000 n=10+10)
RuneCount/lenruneslice/MixedLength 104ns ± 2% 50ns ± 1% -51.71% (p=0.000 n=10+9)
Stefan Steiger sottolinea il post sul blog " Normalizzazione del testo in Go "
Cos'è un personaggio?
Come menzionato nel post sul blog delle stringhe , i personaggi possono estendersi su più rune .
Ad esempio, un ' e
' e '◌́◌́' (acuto "\ u0301") possono combinarsi per formare 'é' (" e\u0301
" in NFD). Insieme, queste due rune sono un personaggio .
La definizione di un personaggio può variare a seconda dell'applicazione.
Per la normalizzazione lo definiremo come:
- una sequenza di rune che inizia con un antipasto,
- una runa che non modifica o combina all'indietro con qualsiasi altra runa,
- seguita da una sequenza forse vuota di non-principianti, cioè rune che fanno (in genere accenti).
L'algoritmo di normalizzazione elabora un carattere alla volta.
Usando quel pacchetto e il suo Iter
tipo , il numero effettivo di "carattere" sarebbe:
package main
import "fmt"
import "golang.org/x/text/unicode/norm"
func main() {
var ia norm.Iter
ia.InitString(norm.NFKD, "école")
nc := 0
for !ia.Done() {
nc = nc + 1
ia.Next()
}
fmt.Printf("Number of chars: %d\n", nc)
}
Qui, utilizza il modulo di normalizzazione Unicode NFKD "Decomposizione compatibilità"
La risposta di Oliver indica la SEGMENTAZIONE DEL TESTO UNICODE come unico modo per determinare in modo affidabile i limiti predefiniti tra alcuni elementi di testo significativi: caratteri, parole e frasi percepiti dall'utente.
Per questo, hai bisogno di una libreria esterna come rivo / uniseg , che esegue la segmentazione del testo Unicode .
Ciò conterà effettivamente " grapheme cluster ", in cui più punti di codice possono essere combinati in un carattere percepito dall'utente.
package uniseg
import (
"fmt"
"github.com/rivo/uniseg"
)
func main() {
gr := uniseg.NewGraphemes("👍🏼!")
for gr.Next() {
fmt.Printf("%x ", gr.Runes())
}
// Output: [1f44d 1f3fc] [21]
}
Due grafemi, anche se ci sono tre rune (punti di codice Unicode).
Puoi vedere altri esempi in " Come manipolare le stringhe in GO per invertirle? "
👩🏾🦰 da solo è un grafema, ma, dall'unicode al convertitore di punti di codice , 4 rune: