Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将Unicode码点号转换为Unicode字符_Python_Unicode - Fatal编程技术网

Python 将Unicode码点号转换为Unicode字符

Python 将Unicode码点号转换为Unicode字符,python,unicode,Python,Unicode,我正在使用Python3中的argparse库从命令行参数中读取Unicode字符串。这些字符串通常包含“普通”Unicode字符(扩展拉丁语等),但有时——特别是当字符属于从右向左的脚本时——将字符串编码为Unicode码点更容易,如\u0644。但是argparse将这些指示符视为一个字符序列,并且不会将它们转换为它们指定的字符。例如,如果命令行参数为 ... -a "abc\06d2d" ... 那么我在argparse变量中得到的是 "abc\06d2d" 而不是预期的 "abcےd

我正在使用Python3中的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()或regex来匹配整个内容,而不是逐个字符,但下面的代码实际上只是一个示例。似乎我根本不必创建自己的函数来完成此操作,特别是在某些情况下,它似乎是自动发生的。)

---------我的代码如下---------


您可能想了解的是
raw\u unicode\u 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转义序列相匹配,如
\uxxxxx
。如果只想匹配
\uxxx
,请使用正则表达式,如下所示:

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)

一种简洁、灵活的处理方法是使用正则表达式:

return re.sub(
    r"\\u([0-9A-Fa-f]{4})",
    lambda m: chr(int(m[1], 16)),
    sInString
)

谢谢——我想有更简洁的方法来编写函数,而你的方法肯定是这样的!为了清晰起见,我把它留得不简洁(因为我很懒)。但我真正想要的是一种避免滚动我自己的解析器的方法——我觉得我缺少了一种完全不需要编写解析器的automagic方法。我想你的第一种方法或多或少就是我想要的(我可能会称之为SomeString.encode('utf-8')。encode('raw_Unicode_escape'))。不幸的是,我正在运行Python 3,这似乎只在Python 2中起作用。具体地说,在Python 3中,它在第二步(使用encode('raw_unicode_escape')的步骤中抱怨“'bytes'对象没有属性'encode'”。我将对此进行一点研究,看看是否能够解决P2和3之间的差异…对于Python 3来说,解决这个问题很简单:只需在第二步中使用decode(),而不是encode()。例如(不考虑错误测试)sString.encode('utf-8')。decode('raw_unicode_escape')。我将此标记为解决方案(属于我想要的类型,即使用内置Python转换,而不是解析字符串)。对于稍后来到这里的任何人:请参阅Artyer针对Python 2的版本,或我针对Python 3的微小修订版。@MikeMaxwell Oops。它的意思是
decode
。它只是一个输入错误。在Python2中,您可以直接
解码它。
return re.sub(
    r"\\u([0-9A-Fa-f]{4})",
    lambda m: chr(int(m[1], 16)),
    sInString
)