如何在Python中确定utf-8编码字符串的字节长度?

use*_*862 23 python unicode utf-8

我正在使用Amazon S3上传,但是因为密钥名称太长而无法解决问题.S3按字节限制密钥的长度,而不是字符.

来自文档:

密钥的名称是一系列Unicode字符,其UTF-8编码长度最多为1024字节.

我还尝试在文件名中嵌入元数据,因此我需要能够使用Python计算字符串的当前字节长度,以确保元数据不会使密钥太长(在这种情况下,我将不得不使用单独的元数据文件).

如何确定utf-8编码字符串的字节长度?同样,我对字符长度感兴趣...而不是用于存储字符串的实际字节长度.

Die*_*Epp 36

def utf8len(s):
    return len(s.encode('utf-8'))
Run Code Online (Sandbox Code Playgroud)

在Python 2和3中正常工作.


Mar*_*eed 8

使用字符串'encode'方法从字符串转换为字节字符串,然后像正常一样使用len():

>>> s = u"¡Hola, mundo!"                                                      
>>> len(s)                                                                    
13 # characters                                                                             
>>> len(s.encode('utf-8'))   
14 # bytes
Run Code Online (Sandbox Code Playgroud)

  • 请不要使用`str`作为变量名!这将导致悲伤的结束. (6认同)

Mar*_*som 5

len正如其他答案所示,对字符串进行编码并在结果上使用效果很好。它确实需要构建一个字符串的一次性副本 - 如果您正在处理非常大的字符串,这可能不是最佳的(尽管我认为 1024 字节不是很大)。UTF-8 的结构允许您非常轻松地获得每个字符的长度,甚至无需对其进行编码,尽管对单个字符进行编码可能仍然更容易。我在这里介绍了这两种方法,它们应该给出相同的结果。

def utf8_char_len_1(c):
    codepoint = ord(c)
    if codepoint <= 0x7f:
        return 1
    if codepoint <= 0x7ff:
        return 2
    if codepoint <= 0xffff:
        return 3
    if codepoint <= 0x10ffff:
        return 4
    raise ValueError('Invalid Unicode character: ' + hex(codepoint))

def utf8_char_len_2(c):
    return len(c.encode('utf-8'))

utf8_char_len = utf8_char_len_1

def utf8len(s):
    return sum(utf8_char_len(c) for c in s)
Run Code Online (Sandbox Code Playgroud)

  • 请注意,作为不制作副本的交换,这需要大约 180 倍的时间,是`len(s.encode('utf-8'))`,至少在我的 python 3.3.2 上,1000 个 utf8 字符的字符串[生成自这里的代码](http://stackoverflow.com/a/1477572/344821)。(如果你用 C 编写相同的算法,它的速度可能相当。) (3认同)