194 votes

Aller la longueur de la chaîne de langue

Comment puis-je obtenir le nombre de caractères d'une chaîne dans Go?

Par exemple, si j'ai une chaîne "hello", la méthode devrait renvoyer 5. J'ai vu que len (str) renvoyait le nombre d'octets et non le nombre de caractères.

247voto

VonC Points 414372

Vous pouvez essayer d' RuneCountInString de l'utf8 paquet.

renvoie le nombre de runes en p

que, comme l'illustre ce script: la longueur du "Monde" pourrait être de 6 (en Chinois: "世界"), mais sa rune nombre est 2:

package main

import "fmt"
import "unicode/utf8"

func main() {
    fmt.Println("Hello, 世界", len("世界"), utf8.RuneCountInString("世界"))
}

Phrozen ajoute dans les commentaires:

En fait, vous pouvez le faire len() plus de runes par juste de conversion de type.
len([]rune("世界")) imprime 2. Au leats en Aller 1.3.

6voto

masakielastic Points 431

Si vous devez prendre en compte les grappes de graphèmes, utilisez le module regexp ou unicode. Compter le nombre de points de code (runes) ou d'octets est également nécessaire pour la validation car la longueur du cluster de graphèmes est illimitée. Si vous souhaitez éliminer les séquences extrêmement longues, vérifiez si elles sont conformes au format texte compatible avec les flux .

 package main

import (
    "regexp"
    "unicode"
    "strings"
)

func main() {

    str := "\u0308" + "a\u0308" + "o\u0308" + "u\u0308"
    str2 := "a" + strings.Repeat("\u0308", 1000)

    println(4 == GraphemeCountInString(str))
    println(4 == GraphemeCountInString2(str))

    println(1 == GraphemeCountInString(str2))
    println(1 == GraphemeCountInString2(str2))

    println(true == IsStreamSafeString(str))
    println(false == IsStreamSafeString(str2))
}


func GraphemeCountInString(str string) int {
    re := regexp.MustCompile("\\PM\\pM*|.")
    return len(re.FindAllString(str, -1))
}

func GraphemeCountInString2(str string) int {

    length := 0
    checked := false
    index := 0

    for _, c := range str {

        if !unicode.Is(unicode.M, c) {
            length++

            if checked == false {
                checked = true
            }

        } else if checked == false {
            length++
        }

        index++
    }

    return length
}

func IsStreamSafeString(str string) bool {
    re := regexp.MustCompile("\\PM\\pM{30,}") 
    return !re.MatchString(str) 
}
 

5voto

zzzz Points 23017

Cela dépend beaucoup de votre définition de ce qu'est un "personnage". Si "rune égale un personnage" convient à votre tâche (généralement, ce n'est pas le cas), la réponse de VonC est parfaite pour vous. Sinon, il faut probablement noter qu'il existe peu de situations où le nombre de runes dans une chaîne Unicode est une valeur intéressante. Et même dans ces situations, il est préférable, si possible, de déduire le nombre en "parcourant" la chaîne lors du traitement des runes afin d'éviter de doubler l'effort de décodage UTF-8.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X