如何在Python中正确打印Unicode字符列表?

5

我希望你能够帮我翻译一下有关IT技术的内容。需要翻译的内容是如何在Python字符串中搜索表情符号。例如:

em_test = ['\U0001f680']
print(em_test)
['']
test = 'This is a test string '
if any(x in test for x in em_test):
    print ("yes, the emoticon is there")
else: 
    print ("no, the emoticon is not there")

yes, the emoticon is there

如果在文本中搜索“em_test”,

'这是一个测试字符串'

我可以找到它。

因此,我已经创建了一个包含所有我想要通过它们的Unicode定义的表情符号的CSV文件。CSV文件如下所示:

\U0001F600

\U0001F601

\U0001F602

\U0001F923

当我导入并打印它时,实际上我得到的不是表情符号,而只是文本表示:

['\\U0001F600',
 '\\U0001F601',
 '\\U0001F602',
 '\\U0001F923',
...
]

因此,我不能使用它来在另一个字符串中搜索这些表情符号...... 我不知道我错过了什么,但我知道双反斜杠\只是单斜杠的表示方式,但是某种方式Unicode读取器却无法识别...... 有什么建议吗?

你确定你没有任何换行符吗? - Ma0
2个回答

3

您可以使用 .decode('unicode-escape') 解码这些 Unicode 转义序列。但是,.decode 是一个 bytes 方法,因此如果这些序列是文本而不是字节,则需要先将它们编码为字节。或者,您可以在二进制模式下打开 CSV 文件,以将这些序列作为 bytes 而不是文本字符串读取(可能)。

只是为了好玩,我还会使用 unicodedata 获取这些表情符号的名称。

import unicodedata as ud

emojis = [
    '\\U0001F600',
    '\\U0001F601',
    '\\U0001F602',
    '\\U0001F923',
]

for u in emojis:
    s = u.encode('ASCII').decode('unicode-escape')
    print(u, ud.name(s), s)

输出

\U0001F600 GRINNING FACE 
\U0001F601 GRINNING FACE WITH SMILING EYES 
\U0001F602 FACE WITH TEARS OF JOY 
\U0001F923 ROLLING ON THE FLOOR LAUGHING 

这应该比使用ast.literal_eval要快得多。如果您以二进制模式读取数据,它甚至会更快,因为它避免了在读取文件时进行初始解码步骤,并允许您消除.encode('ASCII')调用。
您可以通过使用一些方法使解码更加健壮。
u.encode('Latin1').decode('unicode-escape')

但您的表情数据不应该需要这样做。正如我之前所说,最好以二进制模式打开文件,避免需要对其进行编码。


这很棒并且有效。我只有一个问题,涉及到一些特定的表情符号:'\U00023EB' -> 出现了语法错误:(unicode error) 'unicodeescape' 编解码器无法解码位置0-8的字节:截断的\UXXXXXXXX转义。 - Bullzeye
@Bullzeye Python认为'\U00023EB'是无效的:"大写U" Unicode转义符必须包含8个十六进制数字。我们可以在我的代码中处理它,但最好在构建CSV的代码中修复它。 - PM 2Ring
@Bullzeye 或者,对于适合4个十六进制数字的较小代码点,您可以使用“小u”转义码:'\u23eb'。 'unicode-escape' 可以处理它。 它还可以处理像 '\\x41' 这样的东西。 当然,它也可以处理普通的ASCII文本。 - PM 2Ring
是的,抽象语法树庞大了,但这又怎样? :) 非常好的回答。我喜欢解码/编码技巧。 - Jean-François Fabre
@Jean-FrançoisFabre 啊,对了!我忘记那个小插曲了。我通常很擅长区分罗曼语系的语言,但那时已经很晚了,而且我很匆忙。 - PM 2Ring
显示剩余6条评论

1

1. 保持你的csv文件不变:

这是一个冗长的解决方案,但使用ast.literal_eval可以解决问题:

import ast

s = '\\U0001F600'

x = ast.literal_eval('"{}"'.format(s))
print(hex(ord(x)))
print(x)

我得到了0x1f600(这是正确的字符代码)和一些表情符号()。 (好吧,我不得不从我的控制台复制/粘贴一个奇怪的字符到这个答案文本字段中,但那是我的控制台问题,否则它可以正常工作)

只需用引号括起来,以便ast将输入作为字符串处理。

2. 直接使用字符代码

也许您最好存储字符代码本身而不是\U格式:

print(chr(0x1F600))

做的事情完全相同(所以ast有点过度设计)

你的CSV文件可能包含:

0x1F600
0x1F601
0x1F602
0x1F923

那么在读取它时,chr(int(row[0],16))就可以解决问题: 例如,如果CSV中有1行(或第一行)

with open("codes.csv") as f:
   cr = csv.reader(f)
   codes = [int(row[0],16) for row in cr]

好的 - 打印很棒!我可以请求您详细说明如何读取CSV文件吗?我不理解chr(int(row[0],16))部分 - 例如,这是如何集成到pos_emo_twitter = pandas.read_csv('list pos emoticons.csv')中的? - Bullzeye

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接