Anda dapat mencoba RuneCountInString
dari paket utf8.
mengembalikan jumlah rune dalam hal
bahwa, seperti yang diilustrasikan dalam skrip ini : panjang "Dunia" mungkin 6 (ketika ditulis dalam bahasa Cina: "世界"), tetapi jumlah rune-nya adalah 2:
package main
import "fmt"
import "unicode/utf8"
func main() {
fmt.Println("Hello, 世界", len("世界"), utf8.RuneCountInString("世界"))
}
Phrozen menambahkan dalam komentar :
Sebenarnya Anda bisa melakukan len()
lebih dari rune hanya dengan mengetik casting.
len([]rune("世界"))
akan dicetak 2
. Paling tidak aktif Go 1.3.
Dan dengan CL 108985 (Mei 2018, untuk Go 1.11), len([]rune(string))
sekarang dioptimalkan. ( Masalah perbaikan 24923 )
Compiler mendeteksi len([]rune(string))
pola secara otomatis, dan menggantinya dengan untuk r: = range s call.
Menambahkan fungsi runtime baru untuk menghitung rune dalam sebuah string. Memodifikasi kompiler untuk mendeteksi pola len([]rune(string))
dan menggantinya dengan fungsi runtime penghitungan rune baru.
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 menunjuk ke posting blog " Normalisasi teks di Go "
Apa itu karakter?
Seperti yang disebutkan dalam posting blog string , karakter dapat menjangkau beberapa rune .
Misalnya, ' e
' dan '◌́◌́' (akut "\ u0301") dapat bergabung untuk membentuk 'é' (" e\u0301
" di NFD). Bersama-sama kedua rune ini adalah satu karakter .
Definisi karakter dapat bervariasi tergantung pada aplikasi.
Untuk normalisasi, kami akan mendefinisikannya sebagai:
- urutan rune yang dimulai dengan starter,
- Rune yang tidak mengubah atau menggabungkan mundur dengan Rune lain,
- diikuti oleh barisan non-starter yang mungkin kosong, yaitu rune yang melakukan (biasanya aksen).
Algoritma normalisasi memproses satu karakter pada saat bersamaan.
Menggunakan paket itu dan Iter
tipenya , jumlah sebenarnya "karakter" adalah:
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)
}
Di sini, ini menggunakan bentuk Normalisasi Unicode NFKD "Dekomposisi Kompatibilitas"
Oliver 's jawaban poin untuk UNICODE TEXT SEGMENTASI sebagai satu-satunya cara untuk andal menentukan batas-batas standar di antara unsur-unsur tertentu yang signifikan teks: karakter yang dirasakan pengguna, kata, dan kalimat.
Untuk itu, Anda memerlukan perpustakaan eksternal seperti rivo / uniseg , yang melakukan Segmentasi Teks Unicode .
Itu benar-benar akan menghitung " grapheme cluster ", di mana beberapa titik kode dapat digabungkan menjadi satu karakter yang dirasakan pengguna.
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]
}
Dua grafem, meskipun ada tiga rune (titik kode Unicode).
Anda dapat melihat contoh lain di " Cara memanipulasi string di GO untuk membalikkannya? "
👩🏾🦰 sendiri adalah satu grapheme, tetapi, dari unicode ke konverter poin poin , 4 rune: