当前位置: 首页 > 面试题库 >

有关python中字符的unicode表信息

贺彬
2023-03-14
问题内容

python中有没有一种方法可以获取给定字符的技术信息,例如在Unicode表中显示的那样?(请参阅https://unicode-
table.com/en/

示例:对于字母“Ȅ”

  • 名称>带有双坟墓的拉丁大写字母E
  • Unicode编号> U + 0204
  • HTML代码>Ȅ
  • 团体>拉丁扩展B
  • 小写字母>ȅ

我真正需要的是获取任何Unicode数字(例如U + 0204)对应的名称(带Double Grave的拉丁大写字母E)和小写版本(此处为“ȅ”)。

大致来说:
输入= Unicode数字
输出=对应信息

我能够找到的最接近的东西是fontTools库,但是我似乎找不到任何有关如何使用它的教程/文档。

谢谢。


问题答案:

标准模块unicodedata定义了很多属性,但不是 全部
。快速浏览一下其来源即可确认这一点。

幸运的是unicodedata.txt,不难解析它来自的数据文件。每行仅包含15个;单独的元素,因此非常适合解析。使用ftp://ftp.unicode.org/Public/3.0-Update/UnicodeData-3.0.0.html上元素的描述,可以创建一些类来封装数据。我从该列表中选取了类元素的名称。同一页面上解释了每个元素的含义。

确保先下载ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt和ftp://ftp.unicode.org/Public/UNIDATA/Blocks.txt,并将它们放在与此相同的文件夹中程序。

代码(已通过Python 2.7和3.6测试):

# -*- coding: utf-8 -*-

class UnicodeCharacter:
    def __init__(self):
        self.code = 0
        self.name = 'unnamed'
        self.category = ''
        self.combining = ''
        self.bidirectional = ''
        self.decomposition = ''
        self.asDecimal = None
        self.asDigit = None
        self.asNumeric = None
        self.mirrored = False
        self.uc1Name = None
        self.comment = ''
        self.uppercase = None
        self.lowercase = None
        self.titlecase = None
        self.block = None

    def __getitem__(self, item):
        return getattr(self, item)

    def __repr__(self):
        return '{'+self.name+'}'

class UnicodeBlock:
    def __init__(self):
        self.first = 0
        self.last = 0
        self.name = 'unnamed'

    def __repr__(self):
        return '{'+self.name+'}'

class BlockList:
    def __init__(self):
        self.blocklist = []
        with open('Blocks.txt','r') as uc_f:
            for line in uc_f:
                line = line.strip(' \r\n')
                if '#' in line:
                    line = line.split('#')[0].strip()
                if line != '':
                    rawdata = line.split(';')
                    block = UnicodeBlock()
                    block.name = rawdata[1].strip()
                    rawdata = rawdata[0].split('..')
                    block.first = int(rawdata[0],16)
                    block.last = int(rawdata[1],16)
                    self.blocklist.append(block)
            # make 100% sure it's sorted, for quicker look-up later
            # (it is usually sorted in the file, but better make sure)
            self.blocklist.sort (key=lambda x: block.first)

    def lookup(self,code):
        for item in self.blocklist:
            if code >= item.first and code <= item.last:
                return item.name
        return None

class UnicodeList:
    """UnicodeList loads Unicode data from the external files
    'UnicodeData.txt' and 'Blocks.txt', both available at unicode.org

    These files must appear in the same directory as this program.

    UnicodeList is a new interpretation of the standard library
    'unicodedata'; you may first want to check if its functionality
    suffices.

    As UnicodeList loads its data from an external file, it does not depend
    on the local build from Python (in which the Unicode data gets frozen
    to the then 'current' version).

    Initialize with

        uclist = UnicodeList()
    """
    def __init__(self):

        # we need this first
        blocklist = BlockList()
        bpos = 0

        self.codelist = []
        with open('UnicodeData.txt','r') as uc_f:
            for line in uc_f:
                line = line.strip(' \r\n')
                if '#' in line:
                    line = line.split('#')[0].strip()
                if line != '':
                    rawdata = line.strip().split(';')
                    parsed = UnicodeCharacter()
                    parsed.code = int(rawdata[0],16)
                    parsed.characterName = rawdata[1]
                    parsed.category = rawdata[2]
                    parsed.combining = rawdata[3]
                    parsed.bidirectional = rawdata[4]
                    parsed.decomposition = rawdata[5]
                    parsed.asDecimal = int(rawdata[6]) if rawdata[6] else None
                    parsed.asDigit = int(rawdata[7]) if rawdata[7] else None
                    # the following value may contain a slash:
                    #  ONE QUARTER ... 1/4
                    # let's make it Python 2.7 compatible :)
                    if '/' in rawdata[8]:
                        rawdata[8] = rawdata[8].replace('/','./')
                        parsed.asNumeric = eval(rawdata[8])
                    else:
                        parsed.asNumeric = int(rawdata[8]) if rawdata[8] else None
                    parsed.mirrored = rawdata[9] == 'Y'
                    parsed.uc1Name = rawdata[10]
                    parsed.comment = rawdata[11]
                    parsed.uppercase = int(rawdata[12],16) if rawdata[12] else None
                    parsed.lowercase = int(rawdata[13],16) if rawdata[13] else None
                    parsed.titlecase = int(rawdata[14],16) if rawdata[14] else None
                    while bpos < len(blocklist.blocklist) and parsed.code > blocklist.blocklist[bpos].last:
                        bpos += 1
                    parsed.block = blocklist.blocklist[bpos].name if bpos < len(blocklist.blocklist) and parsed.code >= blocklist.blocklist[bpos].first else None
                    self.codelist.append(parsed)

    def find_code(self,codepoint):
        """Find the Unicode information for a codepoint (as int).

        Returns:
            a UnicodeCharacter class object or None.
        """
        # the list is unlikely to contain duplicates but I have seen Unicode.org
        # doing that in similar situations. Again, better make sure.
        val = [x for x in self.codelist if codepoint == x.code]
        return val[0] if val else None

    def find_char(self,str):
        """Find the Unicode information for a codepoint (as character).

        Returns:
            for a single character: a UnicodeCharacter class object or
            None.
            for a multicharacter string: a list of the above, one element
            per character.
        """
        if len(str) > 1:
            result = [self.find_code(ord(x)) for x in str]
            return result
        else:
            return self.find_code(ord(str))

加载后,您现在可以使用

>>> ul = UnicodeList()     # ONLY NEEDED ONCE!
>>> print (ul.find_code(0x204))
{LATIN CAPITAL LETTER E WITH DOUBLE GRAVE}

默认情况下显示为字符 名称 (Unicode将其称为“代码点”),但您也可以检索其他属性:

>>> print ('%04X' % uc.find_code(0x204).lowercase)
0205
>>> print (ul.lookup(0x204).block)
Latin Extended-B

并且(只要您没有获得None)甚至将它们链接起来:

>>> print (ul.find_code(ul.find_code(0x204).lowercase))
{LATIN SMALL LETTER E WITH DOUBLE GRAVE}

它不依赖于您的特定Python版本;您可以随时从unicode.org下载更新列表,并确保获得最新信息:

import unicodedata
>>> print (unicodedata.name('\U0001F903'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: no such name
>>> print (uclist.find_code(0x1f903))
{LEFT HALF CIRCLE WITH FOUR DOTS}

(经Python 3.5.3。测试)。

当前定义了两个查找功能:

  • find_code(int)通过 代码点将 字符信息查找为整数。
  • find_char(string)在中查找字符的字符信息string。如果只有一个字符,则返回一个UnicodeCharacter对象;否则,返回一个对象。如果还有更多,它将返回对象 列表

之后import unicodelist(假设您将其另存为unicodelist.py),则可以使用

>>> ul = UnicodeList()
>>> hex(ul.find_char(u'è').code)
'0xe8'

查找任何字符的十六进制代码,以及列表理解,例如

>>> l = [hex(ul.find_char(x).code) for x in 'Hello']
>>> l
['0x48', '0x65', '0x6c', '0x6c', '0x6f']

对于更长的字符串。 请注意, 如果您想要的只是一个字符串的 十六进制 表示,那么 实际上并不需要所有这些 !这足以:

 l = [hex(ord(x)) for x in 'Hello']

该模块的目的是使您可以轻松访问 其他 Unicode属性。一个更长的例子:

str = 'Héllo...'
dest = ''
for i in str:
    dest += chr(ul.find_char(i).uppercase) if ul.find_char(i).uppercase is not None else i
print (dest)

HÉLLO...

并根据您的示例显示字符的属性列表:

letter = u'Ȅ'
print ('Name > '+ul.find_char(letter).name)
print ('Unicode number > U+%04x' % ul.find_char(letter).code)
print ('Bloc > '+ul.find_char(letter).block)
print ('Lowercase > %s' % chr(ul.find_char(letter).lowercase))

(我省略了HTML;这些名称未在Unicode标准中定义。)



 类似资料:
  • 问题内容: 我正在使用Sql Server 2008 R2 Enterprise。我正在编写一个能够从Sql表中插入,更新,删除和选择记录的应用程序。当涉及包含to,as拧,胆和啪等 特殊字符 的记录时,应用程序会出错。 这是发生了什么: 命令: 插入新记录,但“名称”字段为,因此字符更改为。 命令: 返回正确的记录,因此再次将字符替换为该记录并返回该记录。 问题: 是否可以使Sql Server

  • 问题内容: 在2010年,您是否会在大型Web门户中提供包含UTF-8字符的URL? 根据URL上的RFC禁止使用Unicode字符。必须对它们进行百分比编码以符合标准。 不过,我的主要观点是提供未编码的字符,其唯一目的是拥有美观的URL,因此百分比编码已被淘汰。 不论RFC怎么说,所有主流浏览器似乎都可以解析这些URL。不过,我的总体印象是,离开网络浏览器领域时,它变得非常不稳定: URL复制并

  • 问题内容: 我已经阅读了Stackoverflow上的其他问题,但还没有结束。抱歉,如果已经可以回答,但是我没有任何建议在那里工作。 一切都很好,然后我尝试使用其中包含挪威字符的内容(或更像unicode的内容): 如何匹配øæå等典型的unicode字符?我希望能够同时在上述标记组和文件名标记组中匹配这些字符。 问题答案: 您需要指定标志, 并 使用前缀将您的字符串输入为Unicode字符串:

  • 问题内容: 这个问题看起来很尴尬,但我一直找不到答案。 与下面的C#代码行等效的PHP是什么? 此示例创建一个带有单个Unicode字符的字符串,该字符串的“ Unicode数值”为十六进制的1000(十进制的4096)。 也就是说,在PHP中,如何创建一个具有“ Unicode数值”已知的Unicode字符的字符串? 问题答案: 因为JSON直接支持语法,所以我想到的第一件事是: 另一种选择是使

  • 问题内容: 我有一个树形结构,其中的关键字可能包含一些拉丁字符。我有一个遍历树上所有叶子并在特定条件下将每个关键字添加到列表的函数。 这是我将这些关键字添加到列表中的代码: 如果在这种情况下的关键字是,那么我的输出是: 看来打印功能可以正确显示拉丁字符,但是当我将其添加到列表中时,它就会被解码。 我该如何更改?我需要能够使用标准拉丁字符而不是它们的解码版本来打印列表。 问题答案: 您没有unico

  • 问题内容: 我使用函数对AJAX发送到PHP的JS对象进行字符串化处理。 当JSON.stringify函数将Unicode字符编码为格式(例如)时,就会出现问题。我的问题是如何在PHP中将这些字符转换为常规unicode字符? 问题答案: 看到输出UTF-16?有点卡住 这将转换为UTF-8: