【问题标题】:Converting Unicode codepoints into Unicode character using Python 3.3.1使用 Python 3.3.1 将 Unicode 代码点转换为 Unicode 字符
【发布时间】:2013-04-29 13:00:03
【问题描述】:

我有这个字符串:

sig=45C482D2486105B02211ED4A0E3163A9F7095E81.4DDB3B3A13C77FE508DCFB7C6CC68957096A406C\u0026type=video%2F3gpp%3B+codecs%3D%22mp4v.20.3%2C+mp4a.40.2%22\u0026quality=small\u
0026itag=17\u0026url=http%3A%2F%2Fr6---sn-cx5h-itql.c.youtube.com%2Fvideoplayback%3Fsource%3Dyoutube%26mt%3D1367776467%26expire%3D1367797699%26itag%3D17%26factor%3D1.25%2
6upn%3DpkX9erXUHx4%26cp%3DU0hVTFdUVV9OU0NONV9PTllHOnhGdTVLUThqUWJW%26key%3Dyt1%26id%3Dab9b0e2f311eaf00%26mv%3Dm%26newshard%3Dyes%26ms%3Dau%26ip%3D49.205.30.138%26sparams%
3Dalgorithm%252Cburst%252Ccp%252Cfactor%252Cid%252Cip%252Cipbits%252Citag%252Csource%252Cupn%252Cexpire%26burst%3D40%26algorithm%3Dthrottle-factor%26ipbits%3D8%26fexp%3D9
17000%252C919366%252C916626%252C902533%252C932000%252C932004%252C906383%252C904479%252C901208%252C925714%252C929119%252C931202%252C900821%252C900823%252C912518%252C911416
%252C930807%252C919373%252C906836%252C926403%252C900824%252C912711%252C929606%252C910075%26sver%3D3\u0026fallback_host=tc.v19.cache2.c.youtube.com

如您所见,它包含两种形式:

  • %xx。例如,%3%2F 等。
  • \uxxxx。例如,\u0026

我需要将它们转换为它们的 unicode 字符表示。我正在使用Python 3.3.1,而urllib.parse.unquote(s) 仅将%xx 转换为它们的Unicode 字符表示。但是,它不会将 \uxxxx 转换为它们的 unicode 字符表示。例如,\u0026 应转换为 &

如何同时转换它们?

【问题讨论】:

  • 我可以理解想要解码这个,但是是什么让你认为你需要“转换为 ASCII”?
  • 我正在解析字符串,并且想要拆分它。
  • 你也可以解析 Unicode 字符串。
  • @doomster: \u0026 使字符串难以理解。 & 如果我先转换它会好得多。我正在学习 Python,所以这对我很重要。
  • 嗯,有一个 Unicode 字符 '\u20ac' 恕我直言,比 9 个字符 '%e2%82%ac' 更容易解析,每个字符都可以出现在其他字母的表示中。

标签: python string unicode python-3.x


【解决方案1】:

两种选择:

  • 选择将其解释为 JSON;该格式使用相同的转义码。输入确实需要有引号才能被视为字符串。

  • 编码为 latin 1(以保留字节),然后使用 unicode_escape 编解码器进行解码:

    >>> urllib.parse.unquote(sig).encode('latin1').decode('unicode_escape')
    '45C482D2486105B02211ED4A0E3163A9F7095E81.4DDB3B3A13C77FE508DCFB7C6CC68957096A406C&type=video/3gpp;+codecs="mp4v.20.3,+mp4a.40.2"&quality=small&itag=17&url=http://r6---sn-cx5h-itql.c.youtube.com/videoplayback?source=youtube&mt=1367776467&expire=1367797699&itag=17&factor=1.25&upn=pkX9erXUHx4&cp=U0hVTFdUVV9OU0NONV9PTllHOnhGdTVLUThqUWJW&key=yt1&id=ab9b0e2f311eaf00&mv=m&newshard=yes&ms=au&ip=49.205.30.138&sparams=algorithm%2Cburst%2Ccp%2Cfactor%2Cid%2Cip%2Cipbits%2Citag%2Csource%2Cupn%2Cexpire&burst=40&algorithm=throttle-factor&ipbits=8&fexp=917000%2C919366%2C916626%2C902533%2C932000%2C932004%2C906383%2C904479%2C901208%2C925714%2C929119%2C931202%2C900821%2C900823%2C912518%2C911416%2C930807%2C919373%2C906836%2C926403%2C900824%2C912711%2C929606%2C910075&sver=3&fallback_host=tc.v19.cache2.c.youtube.com'
    

这会解释 \u 转义码,就像 Python 在 Python 源代码中读取字符串文字时所做的那样。

【讨论】:

  • 第二个选项有效。你能解释一下它是如何工作的吗?你为什么使用encode('latin1') 然后decode('unicode_escape')?他们每个人都做什么?
  • 我建议使用使用您的本机编码的 encode() 。 latin1 确实只会导致比它解决的问题更多的问题。如果您已经有 unicode 字符,它们将是可编码的。另一种方式是您需要关心不适合编码的字节。在这方面,如果您知道需要处理二进制数据,您应该真正使用“surrogateescape”错误处理。
  • @Nawaz - 为了对 \u 序列进行转义,您需要调用 decode('unicode_escape') 来解码 unicode 转义序列。但是decode 仅适用于字节对象而不适用于 unicode 字符串(这是您从 parse.unquote 获得的)。他首先调用 encode 以从字符串中获取字节,然后将字节解码回 unicode 以获取带有未转义序列的文本。
  • @underrun:使用 latin1 可以安全地从真正是数据的 unicode 字符中获取回字节。由于这是 URL 编码的数据,我们可以先解码为 un​​icode_escape,然后再进行 URL 解码,以避免与 url 编码的字符发生任何潜在冲突。
【解决方案2】:

如果我猜对了,这或多或少是一个 URL。 '%xx' 对允许字符集之外的单个字节进行编码。 '\uxxxx' 编码一个 Unicode 代码点。我认为 URL 将 Unicode 字符编码为 UTF-8,然后将允许的字符集之外的字节编码为 '%xx' 是正常的(这会影响所有多字节 UTF-8 序列)。令人惊讶的是,已经有 '%xx' 编码的字节,因为翻译 Unicode 代码点会使转换不可逆。

确保您进行了测试并且可以验证实际结果,因为这似乎是不安全的。至少不完全理解这里的要求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-21
    • 1970-01-01
    • 2018-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多