Wie kann ich die Anzahl der Zeichen einer Zeichenfolge in Go ermitteln?
Wenn ich beispielsweise eine Zeichenfolge habe "hello"
, sollte die Methode zurückgegeben werden 5
. Ich habe gesehen, dass len(str)
die Anzahl der Bytes und nicht die Anzahl der Zeichen zurückgegeben wird. len("£")
Daher wird 2 anstelle von 1 zurückgegeben, da £ in UTF-8 mit zwei Bytes codiert ist.
string
go
character
string-length
Ammar
quelle
quelle
Antworten:
Sie können es
RuneCountInString
aus dem utf8-Paket versuchen .das, wie in diesem Skript dargestellt : Die Länge von "Welt" könnte 6 sein (wenn auf Chinesisch geschrieben: "世界"), aber seine Runenzahl ist 2:
Phrozen fügt in den Kommentaren hinzu :
Eigentlich kannst du
len()
Runen übergehen, indem du einfach Casting tippst.len([]rune("世界"))
wird gedruckt2
. Bei Leats in Go 1.3.Und mit CL 108985 (Mai 2018, für Go 1.11)
len([]rune(string))
ist jetzt optimiert. ( Behebt das Problem 24923 )Der Compiler erkennt das
len([]rune(string))
Muster automatisch und ersetzt es durch den Aufruf von r: = range s.Stefan Steiger verweist auf den Blogbeitrag " Textnormalisierung in Go "
Was ist ein Charakter?
Unter Verwendung dieses Pakets und seines
Iter
Typs wäre die tatsächliche Anzahl von "Zeichen":Hier wird das Unicode-Normalisierungsformular NFKD "Compatibility Decomposition" verwendet.
Oliver ‚s Antwort verweist auf UNICODE TEXT SEGMENTATION als der einzige Weg , um zuverlässig Standard Grenzen zwischen bestimmten wesentlichen Textelemente zu bestimmen: Benutzer wahrgenommenen Zeichen, Wörter und Sätze.
Dafür benötigen Sie eine externe Bibliothek wie rivo / uniseg , die die Unicode-Textsegmentierung durchführt .
Das wird zählen eigentlich „ Graphem - Cluster “, in denen mehrere Codepunkte können in einem benutzer wahrgenommen Charakter kombiniert werden.
Zwei Grapheme, obwohl es drei Runen gibt (Unicode-Codepunkte).
Weitere Beispiele finden Sie unter " Wie manipuliere ich Zeichenfolgen in GO, um sie umzukehren? "
👩🏾🦰 allein ist ein Graphem, aber vom Unicode- zum Codepunktkonverter 4 Runen:
quelle
Es gibt eine Möglichkeit, die Anzahl der Runen ohne Pakete zu ermitteln, indem der String in die Rune [] konvertiert wird als
len([]rune(YOUR_STRING))
:quelle
Hängt sehr von Ihrer Definition ab, was ein "Charakter" ist. Wenn "Rune gleich einem Charakter" für Ihre Aufgabe in Ordnung ist (im Allgemeinen nicht), ist die Antwort von VonC perfekt für Sie. Andernfalls sollte wahrscheinlich beachtet werden, dass es nur wenige Situationen gibt, in denen die Anzahl der Runen in einer Unicode-Zeichenfolge ein interessanter Wert ist. Und selbst in solchen Situationen ist es besser, wenn möglich, die Anzahl abzuleiten, während die Zeichenfolge "durchlaufen" wird, während die Runen verarbeitet werden, um eine Verdoppelung des UTF-8-Dekodierungsaufwands zu vermeiden.
quelle
String
‚s.length()
Methode entweder die Anzahl der Zeichen nicht zurück. Genauso wenig wie CocoaNSString
‚s --length
Methode. Diese geben einfach die Anzahl der UTF-16-Entitäten zurück. Die wahre Anzahl von Codepunkten wird jedoch selten verwendet, da das Zählen linear dauert.Wenn Sie Graphemcluster berücksichtigen müssen, verwenden Sie das Regexp- oder Unicode-Modul. Das Zählen der Anzahl von Codepunkten (Runen) oder Bytes ist auch für die Validierung erforderlich, da die Länge des Graphemclusters unbegrenzt ist. Wenn Sie extrem lange Sequenzen entfernen möchten, überprüfen Sie, ob die Sequenzen dem Stream-sicheren Textformat entsprechen .
quelle
var
außerhalb der Funktionen extrahiert werden.Es gibt verschiedene Möglichkeiten, um eine Zeichenfolgenlänge zu erhalten:
quelle
Ich möchte darauf hinweisen, dass keine der bisher gegebenen Antworten die Anzahl der Zeichen angibt, die Sie erwarten würden, insbesondere wenn Sie mit Emojis zu tun haben (aber auch mit einigen Sprachen wie Thai, Koreanisch oder Arabisch). VonCs Vorschläge geben Folgendes aus:
Dies liegt daran, dass diese Methoden nur Unicode-Codepunkte zählen. Es gibt viele Zeichen, die aus mehreren Codepunkten bestehen können.
Gleiches gilt für die Verwendung des Normalisierungspakets :
Normalisierung ist nicht dasselbe wie Zählen von Zeichen, und viele Zeichen können nicht zu einem Ein-Code-Punkt-Äquivalent normalisiert werden.
Die Antwort von masakielastic kommt nahe, behandelt aber nur Modifikatoren (die Regenbogenflagge enthält einen Modifikator, der daher nicht als eigener Codepunkt gezählt wird):
Die korrekte Aufteilung von Unicode-Zeichenfolgen in (vom Benutzer wahrgenommene) Zeichen, dh Graphemcluster, ist im Unicode-Standardanhang Nr. 29 definiert . Die Regeln finden Sie in Abschnitt 3.1.1 . Das Paket github.com/rivo/uniseg implementiert diese Regeln, damit Sie die richtige Anzahl von Zeichen in einer Zeichenfolge bestimmen können:
quelle
Ich habe versucht, die Normalisierung etwas schneller zu machen:
quelle