python - 将 Unicode 代码点数字转换为 Unicode 字符

标签 python unicode

我正在使用 Python 3 中的 argparse 库从命令行参数读取 Unicode 字符串。这些字符串通常包含“普通”Unicode 字符(扩展拉丁语等),但有时(特别是当字符属于从右到左的脚本时)将字符串编码为 Unicode 代码点会更容易,例如\u0644 。但 argparse 将这些指示符视为字符序列,并且不会将它们转换为它们指定的字符。例如,如果命令行参数是

... -a "abc\06d2d" ...

那么我在 argparse 变量中得到的是

"abc\06d2d"

不是预期的

"abcےd"

(“c”和“d”之间的字符是 yeh baree)。当然这两种结果都是合乎逻辑的,只是我想要的是第二个。

我尝试在解释器中重现这一点,但在大多数情况下,Python3 会自动将“abc\06d2d”之类的字符串转换为“abc-d”。当我使用 argparse 读取字符串时,情况并非如此...

我想出了一个函数来进行转换,见下文。但我觉得我错过了一些更简单的东西。有没有更简单的方法来进行这种转换? (显然我可以使用 str.startswith() 或正则表达式来匹配整个内容,而不是逐个字符地匹配,但下面的代码实际上只是一个说明。似乎我不应该创建自己的函数来匹配整个内容完全执行此操作,特别是因为在某些情况下它似乎会自动发生。)

---------我执行此操作的代码如下---------

def ParseString2Unicode(sInString):
  """Return a version of sInString in which any Unicode code points of the form 
        \uXXXX (X = hex digit)  
     have been converted into their corresponding Unicode characters.
     Example:
         "\u0064b\u0065" 
     becomes
         "dbe"
  """
  sOutString = ""
  while sInString:
      if len(sInString) >= 6 and \
         sInString[0] == "\\" and \
         sInString[1] == "u" and \
         sInString[2] in "0123456789ABCDEF" and \
         sInString[3] in "0123456789ABCDEF" and \
         sInString[4] in "0123456789ABCDEF" and \
         sInString[5] in "0123456789ABCDEF":
          #If we get here, the first 6 characters of sInString represent
          # a Unicode code point, like "\u0065"; convert it into a char:
          sOutString += chr(int(sInString[2:6], 16))
          sInString = sInString[6:]
      else:
          #Strip a single char:
          sOutString += sInString[0]
          sInString = sInString[1:]
  return sOutString        

最佳答案

您可能想要查看的是 raw_unicode_escape 编码。

>>> len(b'\\uffff')
6
>>> b'\\uffff'.decode('raw_unicode_escape')
'\uffff'
>>> len(b'\\uffff'.decode('raw_unicode_escape'))
1

因此,该函数将是:

def ParseString2Unicode(sInString):
    try:
        decoded = sInString.encode('utf-8')
        return decoded.decode('raw_unicode_escape')
    except UnicodeError:
        return sInString

但是,这也匹配其他 unicode 转义序列,例如 \Uxxxxxxxx。如果您只想匹配 \uxxxx,请使用正则表达式,如下所示:

import re

escape_sequence_re = re.compile(r'\\u[0-9a-fA-F]{4}')

def _escape_sequence_to_char(match):
    return chr(int(match[0][2:], 16))

def ParseString2Unicode(sInString):
    return re.sub(escape_sequence_re, _escape_sequence_to_char, sInString)

关于python - 将 Unicode 代码点数字转换为 Unicode 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44554126/

相关文章:

python - 如何突出显示特定的 x 值范围

python - 从字符串的前面剥离 '../'

unicode - 为什么度数符号与 UTF-8 和 unicode 不同?

java - servlet中的编码问题

python - 如何修复Python Neat Openai Retro中的配置错误

python - 在 pyparsing 中嵌套分隔列表而不会导致无限递归?

ios - 如何用上标呈现注册商标

unicode - 🇩🇪 字符在 Swift 字符串中是如何表示的?

php - 字符如何通过表单传输?

python - Pygame 在事件发生后移动 Sprite 坐标