Você pode tentar RuneCountInString
no pacote utf8.
retorna o número de runas em p
que, conforme ilustrado neste script : o comprimento do "Mundo" pode ser 6 (quando escrito em chinês: "世界"), mas sua contagem de runas é 2:
package main
import "fmt"
import "unicode/utf8"
func main() {
fmt.Println("Hello, 世界", len("世界"), utf8.RuneCountInString("世界"))
}
Phrozen acrescenta nos comentários :
Na verdade, você pode fazer len()
sobre runas apenas digitando casting.
len([]rune("世界"))
irá imprimir 2
. No pulo no Go 1.3.
E com o CL 108985 (maio de 2018, para Go 1.11), len([]rune(string))
agora está otimizado. (Conserta problema 24923 )
O compilador detecta o len([]rune(string))
padrão automaticamente e o substitui pela chamada r: = range s.
Adiciona uma nova função de tempo de execução para contar runas em uma sequência. Modifica o compilador para detectar o padrão len([]rune(string))
e o substitui pela nova função de tempo de execução de contagem de runas.
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 aponta para a postagem do blog " Normalização de texto no Go "
O que é um personagem?
Como foi mencionado na postagem do blog em strings , os caracteres podem abranger várias runas .
Por exemplo, um ' e
' e '◌́◌́' (agudo "\ u0301") podem combinar para formar 'é' (" e\u0301
" no NFD). Juntas, essas duas runas são um personagem .
A definição de um personagem pode variar dependendo do aplicativo.
Para normalização , vamos defini-lo como:
- uma sequência de runas que começa com um iniciador,
- uma runa que não modifica ou combina com outras runas,
- seguido por uma sequência possivelmente vazia de não iniciantes, ou seja, runas que fazem (normalmente acentos).
O algoritmo de normalização processa um caractere de cada vez.
Usando esse pacote e seu Iter
tipo , o número real de "caractere" seria:
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)
}
Aqui, isso usa o formulário de Normalização Unicode NFKD "Decomposição de Compatibilidade"
A resposta de Oliver aponta para SEGMENTAÇÃO DE TEXTO UNICODE como a única maneira de determinar com segurança os limites padrão entre certos elementos significativos do texto: caracteres, palavras e frases percebidos pelo usuário.
Para isso, você precisa de uma biblioteca externa como o rivo / uniseg , que faz a Segmentação de Texto Unicode .
Na verdade, isso contará " cluster grafema ", onde vários pontos de código podem ser combinados em um caractere percebido pelo usuário.
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]
}
Dois grafemas, embora existam três runas (pontos de código Unicode).
Você pode ver outros exemplos em " Como manipular seqüências de caracteres no GO para revertê-las? "
👩🏾🦰 sozinho é um grafema, mas, de unicode para conversor de pontos de código , 4 runas: