RuneCountInString
Utf8 paketinden deneyebilirsiniz .
p'de runes sayısını döndürür
Bu senaryoda gösterildiği gibi : "Dünya" nın uzunluğu 6 olabilir (Çince yazıldığında: "世界"), ancak rune sayısı 2'dir:
package main
import "fmt"
import "unicode/utf8"
func main() {
fmt.Println("Hello, 世界", len("世界"), utf8.RuneCountInString("世界"))
}
Phrozen ekler yorumlarda :
Aslında len()
sadece döküm yazarak runes üzerinden yapabilirsiniz .
len([]rune("世界"))
yazdıracaktır 2
. Go 1.3'teki sıçramalarda.
Ve birlikte CL 108985 (Mayıs 2018, Go 1.11 için) len([]rune(string))
ile şimdi optimize edildi. ( 24923 sayısını giderir )
Derleyici len([]rune(string))
kalıbı otomatik olarak algılar ve r: = aralık s aramasıyla değiştirir.
Bir dizedeki runeleri saymak için yeni bir çalışma zamanı işlevi ekler. Deseni algılamak için derleyiciyi değiştirir ve len([]rune(string))
yeni rune sayma çalışma zamanı işleviyle değiştirir.
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 blog yazısı "işaret git Metin normalleşme "
Karakter nedir?
Dizeler blog gönderisinde belirtildiği gibi , karakterler birden fazla runeye yayılabilir .
Örneğin, bir ' e
' ve '◌́◌́' (akut "\ u0301"), NFD'de 'é' (" e\u0301
") oluşturmak için birleşebilir . Bu iki run birlikte bir karakterdir .
Bir karakterin tanımı, uygulamaya bağlı olarak değişebilir. Normalleştirme
için bunu şöyle tanımlayacağız:
- bir marşla başlayan bir dizi runik,
- diğer runeleri değiştirmeyen veya geriye doğru birleştirmeyen bir rune,
- akabinde, boş olmayan başlatıcılar, yani yapan runeler dizisi (tipik olarak aksanlar).
Normalleştirme algoritması bir seferde bir karakteri işler.
Bu paketi ve Iter
türünü kullanarak , gerçek "karakter" sayısı:
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)
}
Burada, bu Unicode Normalizasyon formunu kullanır NFKD "Uyumluluk Ayrıştırma"
Oliver 'ın cevabı işaret UNICODE METİN BÖLÜMLEMESİNE kullanıcı tarafından algılanan karakterler, kelimeler ve cümleler: güvenilir belli önemli metin elemanları arasında varsayılan sınırları belirleyen tek yolu olarak.
Bunun için Unicode Metin Segmentasyonu yapan rivo / uniseg gibi harici bir kütüphaneye ihtiyacınız var .
Bu, aslında birden çok kod noktasının kullanıcı tarafından algılanan bir karakterle birleştirilebileceği " grafik kümesi " ni sayar .
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]
}
Üç rün (Unicode kod noktaları) olmasına rağmen iki grafik.
" GO'da dizeleri tersine çevirmek için nasıl değiştirilir? "
🦰🏾🦰 tek başına bir grafiktir, ancak unicode'dan kod noktaları dönüştürücüsüne , 4 runik: