postgres:如何计算多字节表情符号字符串在 UTF-8 中的显示长度

postgres: how to count multibyte emoji strings display length in UTF-8

Postgres (v11) 将红心 ❤️ 计为两个字符,对于其他带有选择器单位的多字节 UTF-8 字符以此类推。任何人都知道我如何让 postgres 计算真实字符而不是字节数?

例如,我希望下面的两个例子都应该 return 1.

select length('❤️') = 2 (Unicode: 2764 FE0F)

select length('‍♂️') = 4 (Unicode: 1F3C3 200D 2642 FE0F)

更新

感谢指出 postgres 正确计算 Unicode 代码点的人,以及发生这种情况的原因和方式。

除了将表情符号字符串预处理为 table 官方 Unicode 字符字节的字节,在 Python 或类似的字节中,我没有看到任何其他选项,以获得感知长度。

因此,一种方法是忽略变体选择器中的所有字符,如果达到通用标点符号范围则减 2。

这可以转换成 postgres 函数。

python

"""
# For reference, these code pages apply to emojis
Name    Range
Emoticons    1F600-1F64F
Supplemental_Symbols_and_Pictographs     1F900-1F9FF
Miscellaneous Symbols and Pictographs    1F300-1F5FF
General Punctuation  2000-206F
Miscellaneous Symbols    2600-26FF
Variation Selectors  FE00-FE0F
Dingbats     2700-27BF
Transport and Map Symbols    1F680-1F6FF
Enclosed Alphanumeric Supplement     1F100-1F1FF
"""
emojis="‍♂️‍♂️‍♂️‍♂️‍♂️‍♂️‍♂️" # true count is 7, postgres length() returns 28
true_count=0
for char in emojis:
    d=ord(char)
    char_type=None 
    if (d>=0x2000 and d<=0x206F) : char_type="GP" # Zero Width Joiner
    elif (d>=0xFE00 and d<=0xFE0F) : char_type="VS" # Variation Selector
    print(d, char_type)
    if ( char_type=="GP") : true_count-=2
    elif (char_type!="VS" ):  true_count+=1
print(true_count)