截取带emoji表情的utf8字符串

时间:2022-05-20 20:34:50

好久没有写博客了,当然这个锅得甩给忙碌的工作截取带emoji表情的utf8字符串

最近工作中又一次碰到了关于emoji表情的问题:需求要求将用户输入的一段内容,截取8个长度作为标题。app端简单的对内容substr了一下。

然而当在一些特殊情况下,就会出现截取后最后一位乱码的情况。比如内容为:“明天要发奖金啦截取带emoji表情的utf8字符串截取带emoji表情的utf8字符串”,按预期截取后应该是:“明天要发奖金啦截取带emoji表情的utf8字符串”;而实际上截取的结果是:“明天要发奖金啦?”,最后一位是个乱码,看来奖金发不成了。


要细说起编码,那就是一篇很长的论文了,不了解的同学可以度娘、谷哥一下。

这里主要说说utf8编码:

UTF-8是一种变长字节编码方式。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。

#1-byte格式: 0xxxxxxx
#2-byte格式: 110xxxxx 10xxxxxx
#3-byte格式: 1110xxxx 10xxxxxx 10xxxxxx
#4-byte格式: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
......


之前说到过,emoji表情和一些汉字是4-byte的。加之上面的规律。我们就好办了。

#1-byte格式第1个字节为: 0xxxxxxx 最大时为01111111   对应10进制数值127

#2-byte格式第1个字节为: 110xxxxx 最大时为11011111  对应10进制数值223

#3-byte格式第1个字节为: 1110xxxx 最大时为11101111  对应10进制数值239

#4-byte格式第1个字节为: 11110xxx 最大时为11110111  对应10进制数值247


def get_eight_chars(s):
i = 0
print type(s)
s = s.encode("utf-8")
print type(s)
s = list(s)
temp=[]
c = 0
while i < len(s):
k = ord(s[i])
print 'k',k
# 1-byte
if k <= 127:
temp.append(''.join(s[i:i+1]))
i += 1
# 2-byte,跳过 2 bytes
elif k < 224:
temp.append(''.join(s[i:i+2]))
i += 2
# 3-byte,跳过 3 bytes
elif k < 240:
temp.append(''.join(s[i:i+3]))
i += 3
# 4-byte,跳过 4 bytes
else:
temp.append(''.join(s[i:i+4]))
i += 4
c = c + 1
if c==8:
break
return ''.join(temp)