UTF-8 - это кодировка с переменной длиной. Один символ может быть закодирован с использованием одного, двух, трёх или четырёх байтов. Это означает, что нельзя начать чтение строки в кодировке UTF-8 с произвольного байта, так как это может случайно разрушить символ:

In : lion = 'Löwe'
In : lion.encode('utf-8')[2:]
Out: b'\xb6we'
In : lion.encode('utf-8')[2:].decode('utf-8')
...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb6 in position 0: invalid start byte

Также это означает, что для пропуска первых N символов строки их необходимо прочитать и декодировать. Рассчитать смещение заранее невозможно.

Однако можно пропустить фиксированное количество байтов, принимая во внимание некоторые особенности. Вот как может быть закодирован символ в UTF-8:

0xxxxxxx
110xxxxx 10xxxxxx
1110xxxx 10xxxxxx 10xxxxxx
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
Как видно, байт является начальным байтом символа, если его вид не совпадает с 10xxxxxx. Такие байты называются продолжением символа (continuation bytes). Давайте пропустим их:

def cut_bytes(s, n):
result = s.encode('utf-8')[n:]
mask = int('11000000', 2)
conbyte = int('10000000', 2)
while result[0] and result[0] & mask == conbyte:
result = result[1:]

return result.decode('utf-8')


Пример использования:

In : cut_bytes(lion, 2)
Out: 'we'
In : cut_bytes(lion, 1)
Out: 'öwe'

👉
Просмотры: 147
Открыть в MAX Сообщить о неточности

Сообщить о неточности

Опишите, что нужно исправить. Если есть источник, добавьте ссылку.

Вы покидаете datool.ru

Ссылка ведёт на внешний сайт. datool.ru не отвечает за его содержимое — проверьте адрес, прежде чем вводить пароли или платёжные данные.

Переход через 10 с

Перейти