У меня есть строка в unicode, и я должен возвратить первые символы N. Я делаю это:
result = unistring[:5]
но конечно длина строк unicode! = длина символов. Какие-либо идеи? Единственное решение использует ре?
Править: Подробнее
unistring = "Μεταλλικα" #Metallica written in Greek letters
result = unistring[:1]
возвраты->?
Я думаю, что строки unicode составляют два байта (символ), вот почему эта вещь происходит. Если я делаю:
result = unistring[:2]
Я добираюсь
M
который корректен, Так, должен я всегда slice*2, или я должен преобразовать во что-то?
К сожалению, по историческим причинам до Python 3.0 существовало два типа строк. байтовые строки (str
) и строки Unicode (unicode
).
До унификации на Python 3.0 есть два способа объявить строковый литерал: унифицирование = "Μεταλλικα"
- байтовая строка и унифицирование = u "Μεταλλικα"
- строка юникода.
Причина, по которой вы видите ?
при выполнении result = unistring[:1]
, заключается в том, что некоторые символы в тексте Юникода не могут быть корректно представлены в строке, не являющейся юникодом. Вы, вероятно, видели подобную проблему, если когда-либо использовали действительно старый почтовый клиент и получали письма от друзей в таких странах, как Греция, например.
Поэтому на Python 2.x, если Вам нужно работать с Юникодом, Вы должны сделать это явно. Взгляните на это введение в работу с Unicode на Python: Юникод HOWTO
Когда вы говорите:
unistring = "Μεταλλικα" #Metallica written in Greek letters
Вы не имеют строки Unicode. У вас есть Bytestring в (предположительно) UTF-8. Это не то же самое. Строка Unicode является отдельный DataType в Python. Вы получаете Unicode путем декодирования ByteStrings, используя правильную кодировку:
unistring = "Μεταλλικα".decode('utf-8')
или с помощью литерала Unicode в исходном файле с правой декларацией кодирования
# coding: UTF-8
unistring = u"Μεταλλικα"
Строка Unicode будет делать то, что вы хотите, когда вы делаете Unisting [: 5] ]
.
Нет правильного прямого подхода с любым типом «unicode String».
Даже Python «Unicode» utf-16 String имеет символы переменной длины, поэтому вы не можете просто вырезать с USTRING [: 5]. Поскольку некоторые кодовые точки Unicode могут использовать более одного «символа» I.E. Surrogate Pairs.
Так что, если вы хотите сократить 5 точек кода (Примечание. Это не символы ), чтобы вы могли проанализировать текст, см. http: //en.wikipedia. org / wiki / utf-8 и http://en.wikipedia.org/wiki/utf-16 Определения. Таким образом, вам нужно использовать некоторые битовые маски для выяснения границ.
Также вы до сих пор не получаете персонажей. Потому что например. Слово «שָלוֹֹ» - мир на иврите «Шалом» состоит из 4 персонажей и 6 кодовых точек письма «Shin», гласный «буква« Лам », буква« Вав »и гласный« о »и финальная буква« МЕМ ».
Символ не является точкой кода .
То же самое для большинства западных языков, где письмо с диакритиками может быть представлено как два кодовых точка. Поиск примера для «нормализации Unicode».
Итак ... Если вам действительно нужно 5 первых символов, которые вы должны использовать такие инструменты, как библиотека ICU. Например, есть библиотека ICU для Python, которая предоставляет символы границы итератора.