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)
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)