Усечение unicode, таким образом, это соответствует максимальному размеру при кодировании для проводной передачи

Мне кажется, что поведение Firefox корректно. Каково значение 6-го значения в IE (извините, у меня нет удобным протестировать). С тех пор нет никакого фактического значения, если, я предполагаю, что это заполняет его чем-то как 'пустой указатель', который, конечно, кажется, не то, что Вы намеревались иметь, происходят, когда Вы создали массив.

В конце дня, хотя, это действительно не имеет значения, который "корректен", так как действительность - то, что или Вы нацелены только на один браузер, в этом случае можно проигнорировать то, что другие делают, или Вы нацелены на несколько браузеров, в этом случае, Ваш код должен работать над всеми ними. В этом случае очевидное решение никогда не состоит в том, чтобы включать повисшую запятую в инициализатор массива.

, Если у Вас есть проблемы при предотвращении его (например, по некоторым причинам Вы разработали (плохо, по моему скромному мнению) привычка к включению его) и другие проблемы как это, тогда что-то как JSLint мог бы помочь.

27
задан Community 23 May 2017 в 10:31
поделиться

4 ответа

def unicode_truncate(s, length, encoding='utf-8'):
    encoded = s.encode(encoding)[:length]
    return encoded.decode(encoding, 'ignore')

Вот пример строки Юникода, где каждый символ представлен двумя байтами в UTF-8:

>>> unicode_truncate(u'абвгд', 5)
u'\u0430\u0431'
29
ответ дан 28 November 2019 в 05:26
поделиться

Одно из свойств UTF-8 заключается в том, что его легко повторно синхронизировать, то есть легко находить границы символов Юникода в закодированном потоке байтов. Все, что вам нужно сделать, это разрезать закодированную строку на максимальную длину, затем пройти в обратном направлении от конца, удалив все байты, которые> 127 - они являются частью или началом многобайтового символа.

Как написано сейчас, это слишком просто - сотрет до последнего символа ASCII, возможно, всю строку. Что нам нужно сделать, так это проверить отсутствие усеченных двухбайтовых (начинаются с 110yyyxx ) трехбайтовых ( 1110yyyy ) или четырехбайтовых ( 11110zzz )

Реализация Python 2.6 в виде чистого кода. Оптимизация не должна быть проблемой - независимо от того, длины, мы проверяем только последние 1–4 байта.

# coding: UTF-8

def decodeok(bytestr):
    try:
        bytestr.decode("UTF-8")
    except UnicodeDecodeError:
        return False
    return True

def is_first_byte(byte):
    """return if the UTF-8 @byte is the first byte of an encoded character"""
    o = ord(byte)
    return ((0b10111111 & o) != o)

def truncate_utf8(bytestr, maxlen):
    u"""

    >>> us = u"ウィキペディアにようこそ"
    >>> s = us.encode("UTF-8")

    >>> trunc20 = truncate_utf8(s, 20)
    >>> print trunc20.decode("UTF-8")
    ウィキペディ
    >>> len(trunc20)
    18

    >>> trunc21 = truncate_utf8(s, 21)
    >>> print trunc21.decode("UTF-8")
    ウィキペディア
    >>> len(trunc21)
    21
    """
    L = maxlen
    for x in xrange(1, 5):
        if is_first_byte(bytestr[L-x]) and not decodeok(bytestr[L-x:L]):
            return bytestr[:L-x]
    return bytestr[:L]

if __name__ == '__main__':
    # unicode doctest hack
    import sys
    reload(sys)
    sys.setdefaultencoding("UTF-8")
    import doctest
    doctest.testmod()
8
ответ дан 28 November 2019 в 05:26
поделиться

Для форматирования JSON (escape-код unicode, например \ uabcd ), я использую следующий алгоритм для достижения этой цели:

  • Закодируйте строку Unicode в обратную косую черту. формат, который в конечном итоге будет в версии JSON
  • Усечь на 3 байта больше, чем мой окончательный предел
  • Используйте регулярное выражение для обнаружения и отсечения частичного кодирования значения Unicode

Итак (в Python 2.5), с some_string и требованием сократить примерно до 100 байтов:

# Given some_string is a long string with arbitrary Unicode data.
encoded_string = some_string.encode('unicode_escape')
partial_string = re.sub(r'([^\\])\\(u|$)[0-9a-f]{0,3}$', r'\1', encoded_string[:103])
final_string   = partial_string.decode('unicode_escape')

Теперь final_string снова в Unicode, но гарантированно поместится в пакете JSON позже. Я усек до 103, потому что сообщение в формате Unicode будет закодировано в 102 байта.

Заявление об ограничении ответственности: тестировалось только на базовой многоязычной плоскости. Да, я знаю.

1
ответ дан 28 November 2019 в 05:26
поделиться

Это подойдет для UTF8, если вам нравится делать это в регулярном выражении.

import re

partial="\xc2\x80\xc2\x80\xc2"

re.sub("([\xf6-\xf7][\x80-\xbf]{0,2}|[\xe0-\xef][\x80-\xbf]{0,1}|[\xc0-\xdf])$","",partial)

"\xc2\x80\xc2\x80"

Его охват от U + 0080 (2 байта) до U + 10FFFF (4 байта) строки utf8

Это действительно просто, как и алгоритм UTF8

От U + 0080 до U + 07FF Потребуется 2 байта 110yyyxx 10xxxxxx Это означает, что если вы видите в конце только один байт, например 110yyyxx (от 0b11000000 до 0b11011111) Это [\ xc0- \ xdf] , он будет частичным.

От U + 0800 до U + FFFF необходимо 3 байта 1110yyyy 10yyyyxx 10xxxxxx Если в конце вы видите только 1 или 2 байта, это будет неполный. Он будет соответствовать этому шаблону [\ xe0- \ xef] [\ x80- \ xbf] {0,1}

Из U + 10000 – U + 10FFFF необходимо 4 байта 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx Если в конце вы увидите от 1 до 3 байтов, это будет частичный Он будет соответствовать этому шаблону [\ xf6- \ xf7] [\ x80- \ xbf] {0,2}

Обновление:

Если вам нужна только базовая многоязычная плоскость, вы можете отбросить последний шаблон. Так и будет.

re.sub("([\xe0-\xef][\x80-\xbf]{0,1}|[\xc0-\xdf])$","",partial)

Дайте мне знать, если есть какие-то проблемы с этим регулярным выражением.

2
ответ дан 28 November 2019 в 05:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: