11
votes

Retourner les premiers caractères d'une chaîne unicode

J'ai une chaîne à Unicode et j'ai besoin de renvoyer les premiers n caractères. Je fais cela: xxx pré>

mais bien sûr la longueur des chaînes Unicode! = Longueur des caractères. Des idées? La seule solution utilise re? P>

EDIT: Plus d'infos p>

result = unistring[:2]


4 commentaires

Êtes-vous sûr de disposer d'une chaîne unicode et non (disons) une bytatring avec des données UTF-8? Si oui, comment définissez-vous le «caractère»? (Les chaînes Unicode sont des chaînes de codépoints (dans les constructions UCS-4) ou de codeUnits.)


De notre hôte: Joelonsoftware.com/articles/unicode.html


Va, s'il vous plaît pas. Ce n'est pas vraiment applicable ici.


En fait, c'est. L'OP est clairement confus à propos de Unicode contre UTF-8.


3 Réponses :


7
votes

Lorsque vous dites: xxx

vous ne pas avoir une chaîne unicode. Vous avez un obstacle à (probablement) UTF-8. Ce n'est pas la même chose. Une chaîne Unicode est un type de données séparé dans Python. Vous obtenez unicode en décodant des byterstrings à l'aide du bon codage: xxx

ou à l'aide du littéral unicode dans un fichier source avec la déclaration de codage droite xxx < / Pré>

La chaîne Unicode fera ce que vous voulez quand vous faites UniSistre [: 5] .


6 commentaires

Vous aurez besoin de "#coding: utf-8" avant l'exemple .decode () également, et le fichier doit être réellement enregistré dans UTF-8. Python 2.x par défaut par défaut à ASCII lors de la décodage des scripts. Toute utilisation des caractères non-ASCII nécessite que la ligne de codage indique le codage utilisé pour enregistrer le fichier.


Dans Python 2.5 et plus tard, vous avez besoin de la déclaration de codage sur n'importe quel fichier source avec contenus non ASCII, oui. (Avant, il s'agit juste d'un avertissement.) La déclaration de codage ne changera cependant pas la signification du code, car il ne s'agit que d'octets dans une bytretring.


-1 Ceci n'est pas correct u "Quelque test unicode" [: 5] peut donner une séquence illégale, car l'UTF-16 est un codage de largeur variable, de sorte que la chaîne "Unicode" n'est pas correcte comme une chaîne UTF-8 de coupe


Vous semblez être confondu entre UTF-16 et Unicode. Python utilise uniquement UTF-16 pour UNICODE dans les constructions UCS-2 (qui est principalement uniquement sous Windows.) Dans les constructions UCS-4, la tranchée Unicode fonctionne bien (c'est pourquoi vous devez utiliser des constructions UCS-4.). Dans UCS-2 construit, cela fonctionne bien pour tout personnage BMP, ce que l'OP utilisait.


Par défaut Python est en construction avec UCS-2, même sur Linux. Je sais qu'il est possible d'utiliser des constructions UCS-4, mais elles ne sont pas communes. Donc, dans tous les cas supposant que la chaîne puisse être coupée "comme" "est fausse. Sauf si vous travaillez uniquement dans BMP. En tout cas, il s'agit d'une mauvaise approche. Voir ma réponse ci-dessous pour la raison pour laquelle.


La valeur par défaut est UCS-2, mais la plupart des distributions Linux utilisent en effet UCS-4. Juste jeter un oeil à Sys.maxunicode sur un système typique. Lorsque vous utilisez une construction UCS-2 et des caractères non-BMP, il n'y a pas de bon moyen de trancher, peu importe.



7
votes

Malheureusement pour des raisons historiques avant Python 3.0, il existe deux types de chaînes. Strings d'octets ( STR ) et des chaînes Unicode ( Unicode ) .

Avant de l'unification dans Python 3.0 Il existe deux façons de déclarer une chaîne littéral: unitring = "μεταλλικα" qui est une chaîne d'octets et unisson = u "μεταλλικα" qui est une chaîne unicode.

la raison pour laquelle vous voyez ? quand vous faites résultat = déminage [: 1] est dû au fait que certains des caractères de votre texte Unicode ne peuvent pas être correctement représentés dans le non-présent. String Unicode. Vous avez probablement vu ce genre de problème si vous avez déjà utilisé un très ancien client de messagerie et reçu des courriels d'amis dans des pays comme la Grèce par exemple.

Donc, dans Python 2.x Si vous devez gérer UNICODE, vous devez le faire explicitement. Jetez un coup d'œil à cette introduction à traiter avec Unicode en Python: Unicode Howto < / p>


2 commentaires

"Μεταλλικα" n'est pas une chaîne ASCII. C'est une chaîne d'octets dans l'encodage utilisé pour enregistrer le script.


Vous avez raison, il est plus correct de faire référence à ceux-ci comme des chaînes d'octets plutôt que des chaînes ASCII, j'ai mis à jour la réponse en conséquence. Ce que j'essayais vraiment d'exprimer était que le texte ASCII (ou la chaîne d'octet équivalente en fonction des pages de code de votre ordinateur) est la seule chose qui puisse être manipulée en toute sécurité avec des chaînes d'octets.



4
votes

Il n'y a pas correcte approche directe avec tout type de « chaîne Unicode ».

Même Python "Unicode" chaîne UTF-16 a des caractères de longueur variable, vous ne pouvez pas simplement couper avec ustring [5]. Parce que certains points de code Unicode peuvent utiliser plus d'un « caractère » à savoir des paires Surrogate.

Donc, si vous voulez couper 5 points de code (notez ce ne sont pas caractères ) afin que vous puissiez analyser le texte, voir http://en.wikipedia.org/wiki/UTF-8 et http://en.wikipedia.org/wiki/UTF-16 définitions. Donc, vous devez utiliser des masques de bits pour comprendre les limites.

Aussi, vous ne comprends toujours pas les personnages. Parce que par exemple. Parole « שָלוֹם » - la paix en hébreu « Shalom » se compose de 4 caractères et 6 points de code lettre « tibia », voyelle « a » lettre « lamed », la lettre « vav » et voyelle « o » et la lettre finale « mem ».

caractère est pas point de code .

Même chose pour la plupart des langues occidentales où une lettre avec diacritiques peut être représentée comme deux points de code. Recherche par exemple pour la "normalisation unicode".

Alors ... Si vous avez vraiment besoin 5 premiers caractères que vous devez utiliser des outils comme la bibliothèque de soins intensifs. Par exemple, il est une bibliothèque de soins intensifs pour Python qui fournit des caractères iterator limite.


0 commentaires