如何转义字符串中的 unicode 特殊字符并将其写入 UTF 编码文件

问题描述

我的目标是:

字符串如:

Bitte überprüfen Sie,ob die Dokumente erfolgreich in System eingereicht wurden,und löschen Sie dann die tatsächlichen Dokumente.

转换为:

'Bitte \u00FCberpr\u00FCfen Sie,und l\u00F6schen Sie dann die tats\u00E4chlichen Dokumente.'

并以这种形式将其写入文件(UTF-8 编码)。

解决方法

一个简单的解决方案是ascii()

string = 'Bitte überprüfen Sie,ob die Dokumente erfolgreich in System ' \
         'eingereicht wurden,und löschen Sie dann die tatsächlichen Dokumente.'

print(ascii(string))

输出:

'Bitte \xfcberpr\xfcfen Sie,ob die Dokumente erfolgreich in System eingereicht wurden,und l\xf6schen Sie dann die tats\xe4chlichen Dokumente.'

您也可以使用 unicode-escaperaw-unicode-escape 来实现此目的 (link):

string = 'Bitte überprüfen Sie,und löschen Sie dann die tatsächlichen Dokumente.'

print(string.encode('unicode-escape').decode('raw-unicode-escape'))

输出:

Bitte \xfcberpr\xfcfen Sie,und l\xf6schen Sie dann die tats\xe4chlichen Dokumente.

注意 : ascii() 将使用 \x,\u,\U 转义非 ascii 字符 1 字节、2 字节和 4 字节分别。在您的情况下,您会看到 \x。但是试试这个:

print(ascii('س'))  # '\u0633'

如果您真的想将 \xhh 转义序列转换为 \u00hh ,请对 re.sub() 的结果使用 ascii()

import re
print(re.sub(r'\\x[a-f0-9]{2}',lambda x: r'\u00' + x.group()[-2:].upper(),ascii(string))) 

输出:

'Bitte \u00FCberpr\u00FCfen Sie,und l\u00F6schen Sie dann die tats\u00E4chlichen Dokumente.'

上述方法适用于转义任何非 ascii 字符,如果您只想转义这三个德国字母并且没有其他非 ascii 字符,请查看 str.translate() 方法。

,

另一种解决方案,不依赖于内置的 repr(),而是从头开始实现:

orig = 'Bitte überprüfen Sie,und löschen Sie dann die tatsächlichen Dokumente.'

enc = re.sub('[^ -~]',lambda m: '\\u%04X' % ord(m[0]),orig)

print(enc)

差异:

  • 仅使用 \u 编码,从不使用任何其他序列,而 repr() 使用大约三分之一的字母表(例如,BEL 字符将被编码为 \u0007 而不是 {{ 1}})
  • 指定的大写编码(\a 而不是 \u00FC
  • 不处理平面 0 之外的 unicode 字符(可以轻松扩展,给出应如何表示的规范)
  • 它不会处理任何预先存在的 \u00fc 序列,而 \u 会将它们转换为 repr();可以扩展,也许将 \\u 编码为 \
    \u005C