Python解码问题与汉字

时间:2016-06-28 18:08:56

标签: python python-3.x encoding python-unicode

我正在使用Python 3.5,我正在尝试获取一个字节文本块,该字节文本可能包含或不包含特殊的中文字符,并将其输出到文件中。它适用于不包含中文字符但在执行时会中断的条目。汉字总是一个人的名字,并且总是除了他们名字的英文拼写之外。该文本是JSON格式的,需要在我加载之前进行解码。解码似乎很好,并没有给我任何错误。当我尝试将解码后的文本写入文件时,它会给出以下错误消息:

  

UnicodeEncodeError:'charmap'编解码器无法编码位置14-18中的字符:字符映射到未定义

以下是我在执行任何操作之前获得的原始数据的示例:

 b'  "isBulkRecipient": "false",\r\n      "name": "Name in, English \xef'
 b'\xab\x62\xb6\xe2\x15\x8a\x8b\x8a\xee\xab\x89\xcf\xbc\x8a",\r\n

以下是我正在使用的代码:

recipientData = json.loads(recipientContent.decode('utf-8', 'ignore'))
recipientName = recipientData['signers'][0]['name']
pprint(recipientName)
with open('envelope recipient list.csv', 'a', newline='') as fp:
    a = csv.writer(fp, delimiter=',')
    csvData = [[recipientName]]
    a.writerows(csvData)

recipientContent是从API调用获得的。我不需要在输出文件中包含中文字符。任何建议将不胜感激!

更新

我一直在为每个中断的条目做一些手动变通办法,并且其他条目不包含中文特殊字符,但是从其他语言中获取它们,并且打破了程序。特殊字符仅在名称字段中。因此,名称可能类似于“Ałex”,它是普通字符和特殊字符的混合。在解码包含此信息的字符串之前,我可以将其打印到屏幕上,它看起来像这样:b'name": "A\xc5ex",\r\n

但是在我将其解码为utf-8后,如果我尝试输出它会给我一个错误。错误消息为:UnicodeEncodeError: 'charmap' codec can't encode character 'u0142' in position 2- character maps to -undefined-

我查了一下\ u0142是什么,它是ł特殊角色。

3 个答案:

答案 0 :(得分:0)

警告:提前解决猎枪问题

假设您只想删除所有文件中的所有外来字符(即它们对您将来处理所有其他字段并不重要),您可以简单地忽略所有非ascii字符

recipientData = json.loads(recipientContent.decode('utf-8', 'ignore'))

通过

recipientData = json.loads(recipientContent.decode('ascii', 'ignore'))
像这样,你在将来处理之前删除所有非ascii字符。

我把它称为霰弹枪解决方案,因为它在某些情况下可能无法正常工作:

  1. 显然,如果需要非ascii字符以供将来使用
  2. 如果出现b'\'b"个字符,例如来自utf-16字符的一部分。

答案 1 :(得分:0)

您收到的错误是您写入文件的时间。

在Python 3.x中,当您open()处于文本模式(默认)而未指定encoding=时,Python将使用最适合您的语言环境或语言设置的编码。

如果您使用的是Windows,则会使用charmap编解码器映射到您的语言编码。

虽然您可以直接将字节写入文件,但您可以先通过解码来做正确的事情。正如其他人所说,你应该使用Web服务器指定的编码进行解码。您也可以使用Python Requests模块,它可以为您完成此操作。 (你的例子不能解码为UTF-8,所以我假设你的例子不正确)

要解决您的即时错误,只需将encoding传递给open()即可,该with open('envelope recipient list.csv', 'a', encoding='utf-8', newline='') as fp: 支持数据中包含的字符。 UTF-8编码中的Unicode是显而易见的选择。因此,您应该将代码更改为:

UIAlertController * alert=   [UIAlertController
                                 alertControllerWithTitle:@"Question"
                                 message:@"Do you want first move?"
                                 preferredStyle:UIAlertControllerStyleAlert];
    //First button
   UIAlertAction* ok = [UIAlertAction
                        actionWithTitle:@"YES"
                        style:UIAlertActionStyleDefault
                        handler:^(UIAlertAction * action)
                        {
//Actions if the user press this button
//Dismiss the alertController. It's preferred to be in all actions.
                            [alert dismissViewControllerAnimated:YES completion:nil];
_currentPlayer = @"X";

                        }];

//Second Button
   UIAlertAction* cancel = [UIAlertAction
                            actionWithTitle:@"NO"
                           style:UIAlertActionStyleDefault
                           handler:^(UIAlertAction * action)
                           {
//Actions if the user press this button
//Dismiss the alertController. It's preferred to be in all actions.
                               [alert dismissViewControllerAnimated:YES completion:nil];
_currentPlayer = @"O";

                           }];
    //Add the actions to the alertController
   [alert addAction:ok];
   [alert addAction:cancel];


//present the alertController on the device. If you are writing this in the viewController, you can use self.view, if you are in UIView, then just self
   [self.view presentViewController:alert animated:YES completion:nil];

答案 2 :(得分:0)

将此行添加到您的代码中:

from __future__ import unicode_literals