【问题标题】:Python 3.4 - Remove or ignore emoji characters when writing to filePython 3.4 - 写入文件时删除或忽略表情符号
【发布时间】:2021-10-29 03:06:25
【问题描述】:

我正在尝试解析 XML 文件并将内容写入纯文本文件。到目前为止,我的程序一直在运行,直到它遇到表情符号字符,然后 Python 抛出以下错误:

UnicodeEncodeError: 'charmap' codec can't encode characters in position 177-181: character maps to <undefined>

我去了错误位置,在XML文件中发现了以下表情符号:

我的问题是如何将它们编码为 un​​icode 或在写入文件时完全删除/忽略它们。

当我 print() 到控制台时它输出完美,但在写入文件时抛出错误。

我已经搜索了 Google 和这里​​,但我得到的唯一答案是它们已经被编码为 un​​icode。如您所见,我的是文字?我不确定我说的是否正确。

我正在使用的 XML 文件也具有以下格式:

<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<?xml-stylesheet type="text/xsl" href="sms.xsl"?>
<smses count="1">
  <sms protocol="0" address="+00000000000" date="1346772606199" type="1" subject="null" body="Lorem ipsum dolor sit amet, consectetur adipisicing elit," toa="null" sc_toa="null" service_center="+00000000000" read="1" status="-1" locked="0" date_sent="1346772343000" readable_date="Sep 4, 2012 10:30:06 AM" contact_name="John Doe" />
</smses>

【问题讨论】:

  • 您可以使用try:except: 来捕获错误吗?
  • 你现在用什么代码来写输出?您选择的文件编码不支持代码点;你可以选择一个不同的编码,或者你可以选择处理错误。
  • 我会说这不是一个糟糕的提议。遍历所有字符,并尝试编写它们。
  • @RSerrao:有比逐个处理字符更好的方法。
  • @MartijnPieters 我是一名 Python 新手,如果您能赐教,我会很高兴!

标签: python xml unicode emoji


【解决方案1】:

你有两个选择:

  1. 选择可以处理表情符号代码点的编码。您已打开文件以使用默认编解码器(取决于您的系统)进行编写,或者选择了不支持代码点的显式编码。

    UTF 编码可以很好地处理代码点;我会在这里选择 UTF-8:

    with open(filename, 'w', encoding='utf8') as outfile:
        outfile.write(yourdata)
    
  2. 设置错误处理模式,用替换字符、转义序列替换编解码器无法处理的代码点,或者完全忽略它们。请参阅open() functionerrors 参数:

    errors 是一个可选字符串,它指定如何处理编码和解码错误——这不能用于二进制模式。有多种标准错误处理程序可用,但任何已使用codecs.register_error() 注册的错误处理名称也是有效的。标准名称是:

    • 如果出现编码错误,'strict' 会引发 ValueError 异常。默认值None具有相同的效果。
    • 'ignore' 忽略错误。请注意,忽略编码错误可能会导致数据丢失。
    • 'replace' 导致在存在格式错误的数据的位置插入替换标记(例如 '?')。
    • 'surrogateescape' 将在从 U+DC80 到 U+DCFF 的 Unicode Private Use Area 中将任何不正确的字节表示为代码点。当写入数据时使用surrogateescape 错误处理程序时,这些私有代码点将被转换回相同的字节。这对于处理未知编码的文件很有用。
    • 'xmlcharrefreplace' 仅在写入文件时受支持。编码不支持的字符将替换为相应的 XML 字符引用 &amp;#nnn;
    • 'backslashreplace'(也仅在编写时支持)用 Python 的反斜杠转义序列替换不受支持的字符。

    因此使用errors='ignore' 打开文件将不会写入表情符号代码点,而不是引发错误:

    with open(filename, 'w', errors='ignore') as outfile:
        outfile.write(yourdata)
    

演示:

>>> a_ok = 'The U+1F44C OK HAND SIGN codepoint: \U0001F44C'
>>> print(a_ok)
The U+1F44C OK HAND SIGN codepoint: ?
>>> a_ok.encode('utf8')
b'The U+1F44C OK HAND SIGN codepoint: \xf0\x9f\x91\x8c'
>>> a_ok.encode('cp1251', errors='ignore')
b'The U+1F44C OK HAND SIGN codepoint: '
>>> a_ok.encode('cp1251', errors='replace')
b'The U+1F44C OK HAND SIGN codepoint: ?'
>>> a_ok.encode('cp1251', errors='xmlcharrefreplace')
b'The U+1F44C OK HAND SIGN codepoint: &#128076;'
>>> a_ok.encode('cp1251', errors='backslashreplace')
b'The U+1F44C OK HAND SIGN codepoint: \\U0001f44c'

请注意,'surrogateescape' 选项的空间有限,并且仅对尽可能解码未知编码的文件有用;在任何情况下它都无法处理 Emoji。

【讨论】:

  • 您的第一个建议首先会完美运行。谢谢!大学学习Java一年后,我才开始自学Python。
【解决方案2】:

(编辑:此答案与 Python 2.x 相关,而不是 Python 3.x)

目前,您正在使用默认编码将 unicode 字符串写入文件,该编码不支持表情符号(或者,就此而言,您可能确实需要大量字符)。您可以改为使用支持所有 unicode 字符的 UTF-8 编码来编写。

不要使用file.write( data ),而是尝试file.write( data.encode("utf-8") )

【讨论】:

  • 这是 Python 3;文件对象处理编码。这意味着您不想编写编码字节
  • 啊,抱歉,没有意识到这是python 3。愿意回答吗?
  • 我希望 OP 最好告诉我他是如何写入文件的。
猜你喜欢
  • 2013-07-06
  • 2014-04-05
  • 1970-01-01
  • 2018-05-02
  • 1970-01-01
  • 1970-01-01
  • 2014-07-27
  • 2021-01-08
相关资源
最近更新 更多