将代理对转换为表情符号-python3

我在另一个主题上找到了类似问题的解决方案,但不幸的是,它不适用于我。 这是我的问题:

我正在用代理对unicode制作数据帧,我想在另一个文件中搜索它(例如:“ \ uD83C \ uDFF3”,“ \ u26F9”,“ \ uD83C \ uDDE6 \ uD83C \ uDDE8”):

    with open("unicodes.csv","rt") as csvfile:                                        
        emoticons = pd.read_csv(csvfile,names=["xy"])
        emoticons = pd.DataFrame(emoticons)
        emoticons = emoticons.astype(str)

接下来,我正在阅读带有文本的文件,其中某些行包含代理对unicode:

    for chunk in pd.read_csv(path,names=["xy"],encoding="utf-8",chunksize=chunksize):            
        spam = pd.DataFrame(chunk)
        spam = spam.astype(str)

在此for循环中,我正在检查行是否包含代理对unicode,如果为真,那么我想将此替代对unicode打印为表情符号-这就是为什么我要编码和解码该“ i”值,即str: (来自How to work with surrogate pairs in Python?的解决方案)

        for i in emoticons.xy:
            if spam["xy"].str.contains(i,regex=False).any():                                 
                print(i.encode('utf-16','surrogatepass').decode('utf-16'))

               #printing:
               #\uD83C\uDFF3 
               #\u26F9
               #\uD83C\uDDE6\uD83C\uDDE8

因此,当我启动程序时,它仍然将替代代理对uni打印为str而不是表情符号,但是当我自己将替代对unicode输入到打印函数中时,它可以工作:

    print("\uD83C\uDFF3".encode("utf-16","surrogatepass").decode("utf-16","surrogatepass"))

    #printing:
    #? 

我在做什么错?我尝试通过此方法和其他解决方案制作字符串,但仍然无法正常工作。

编辑:

hexdump -C file.csv
00004b70  5c 75 44 38 33 44 5c 75  44 45 45 39 0a 5c 75 44  |\uD83D\uDEE9.\uD|
00004b80  38 33 44 5c 75 44 45 45  42 0a 5c 75 44 38 33 44  |83D\uDEEB.\uD83D|
00004b90  5c 75 44 45 45 43 0a 5c  75 44 38 33 44 5c 75 44  |\uDEEC.\uD83D\uD|
00004ba0  43 42 41 0a 5c 75 44 38  33 44 5c 75 44 45 38 31  |CBA.\uD83D\uDE81|

EDIT2: 因此,我发现了某种可行的方法,但仍需要改进: https://stackoverflow.com/a/54918256/4789281

我要转换的另一个文件中的文本为外观文件:

"O żółtku zapomniałaś \uD83D\uDE02"
"Piękny outfit \uD83D\uDE0D"

在执行此操作时,另一个主题中的建议是:

print(codecs.decode(i,encoding='unicode_escape',errors='surrogateescape').encode('utf-16','surrogatepass').decode('utf-16'))

我有这样的东西:

O żóÅtku zapomniaÅaÅ ?
PiÄkny outfit ?

所以我的代理配对被替换了,但是我的波兰字符被替换成了奇怪的东西。

cmwapfang 回答:将代理对转换为表情符号-python3

您的路线正确。 为什么要尝试中断,因为读取文件后在“ str”中的内容不是“代理对”,而是代理对的反斜杠编码代码点,编码为文本。

也就是说,文件中的序列“ 5c 75 44 38 33 44”是实际的ASCII字符“ \ uD83D”(总共6个字符),而不是替代代码点0xD83D(在正确解码后会与下一个代理“ \ uDE0D”将是您字符串中的单个字符。

我说的对的部分是:您确实必须将其编码为字节序列,然后再解码回去。错误的是,您必须使用“ latin1”对其进行编码(只是尝试保留字符串上的任何其他非ascii字符-如果您的代码点无法在latin1中表示,它可能会损坏),然后使用特殊的“ unicode转义”编解码器。或charmap编码,它将在字符串上保留您的 other 字符,然后使用相同的编解码器将其解码回去。届时,两个代理字符都将是文本,作为Python字符串中的两个字符:

In [16]: "\\uD83D\\uDE0D".encode("latin1").decode("unicode escape","surrogatepass")                              
Out[16]: '\ud83d\ude0d'

坏消息是-这不是一个非常有效的STR-替代字符本身不应在内部表示中存在-而是应将它们组合为所需的最终字符。因此,尝试将其打印出来会失败:

In [19]: a  = "\\uD83D\\uDE0D".encode("utf-8").decode("unicode escape")                                          

In [20]: print(a)                                                                                                       
---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
<ipython-input-20-bca0e2660b9f> in <module>
----> 1 print(a)

UnicodeEncodeError: 'utf-8' codec can't encode characters in position 0-1: surrogates not allowed

在这里使用“ surrogatepass”错误策略没有帮助-您将获得不可打印的字节序列。

因此,第二次必须对此进行“编码”和“解码”-这次,文本中的字符是实际的“替代”代码点,这些点将是有效的utf-16进行解码。因此,现在的路径是对该序列进行编码,使用“ surrogatepass”对这些字符进行暴力破解,然后从utf-16解码回来-最终将代理对理解为单个字符:

In [30]: a  = "\\uD83D\\uDE0D".encode("unicode escape").decode("unicode escape")                                          

In [31]: a                                                                                                              
Out[31]: '\ud83d\ude0d'

In [32]: b = a.encode("utf-16","surrogatepass").decode("utf-16")                                                       

In [33]: print(b)                                                                                                       
?

总结:

您以utf-8文本格式读取文件,以读取其他可能的非ASCII字符, 将结果编码为“ unicode转义”并将其解码回-这将转换 在文件中扩展了人类可读的“ \ uXXXX”序列作为代理代码点。然后将其转换回utf-16,告诉Python忽略 代理,然后“原样”复制,然后从utf-16解码回去:

def decode_surrogate_ascii(txt):
    interm = txt.encode("latin1").decode("unicode escape")
    return interm.encode("utf-16","surrogatepass").decode("utf-16")

您需要做的就是在数据框上感兴趣的列中应用上述功能:

emoticons = emoticons.apply(pd.Series(lambda row: (decode_surrogate_ascii(item) if isinstance(item,str) else item for item in row ))
本文链接:https://www.f2er.com/3067923.html

大家都在问