繁体   English   中英

Unicode字符串中有多少个可显示字符(日语/中文)

[英]How many displayable characters in a unicode string (Japanese / Chinese)

我需要知道一个包含日文/中文字符的unicode字符串中有多少个可显示字符。

示例代码使问题非常明显:

# -*- coding: UTF-8 -*-
str = '\xe7\x9d\xa1\xe7\x9c\xa0\xe6\x99\x82\xe9\x96\x93'
print len(str)

12

print str

睡眠时间<<<请注意,显示四个字符

我如何从字符串中知道将要显示4个字符?

这个字符串

str = '\xe7\x9d\xa1\xe7\x9c\xa0\xe6\x99\x82\xe9\x96\x93'

unicode代码点的编码表示。 它包含字节,len(str)返回您的字节数

您想知道,该字符串包含多少个unicode代码。 为此,您需要知道什么编码用于编码那些unicode代码。 最受欢迎的编码是utf8 在utf8编码中,一个unicode码点可以占用1到6个字节。 但您一定不要忘记,只需解码字符串即可:

>>> str.decode('utf8')
u'\u7761\u7720\u6642\u9593'

在这里您可以看到4个unicode点。 打印,以查看可打印版本:

>>> print str.decode('utf8')
睡眠時間

并获取大量的unicode代码:

>>> len(str.decode('utf8'))
4

更新 :也请参阅abarnert答案以尊重所有可能的情况。

如果您实际上想要“可显示字符”,则必须做两件事。

首先,您必须将字符串从UTF-8转换为Unicode,如stalk所述:

s = '\xe7\x9d\xa1\xe7\x9c\xa0\xe6\x99\x82\xe9\x96\x93'
u = s.decode('utf-8')

接下来,您必须过滤掉所有不代表可显示字符的代码点。 您可以为此使用unicodedata模块。 category功能可以为您提供任何代码单元的常规类别。 要理解这些类别,请查看从您的Python的unicodedata文档版本链接的Unicode字符数据库版本中的General Categories表

对于使用UCD 5.2.0的Python 2.7.8,您必须做一些解释才能确定什么算作“可显示”,因为Unicode确实没有与“可显示”相对应的任何内容。 但是,假设您已决定所有控件,格式,专用字符和未分配字符均不可显示,而其他所有内容均不可显示。 然后你会写:

def displayable(c):
    return unicodedata.category(c).startswith('C')
p = u''.join(c for c in u if displayable(c))

或者,如果您确定Mn和Me也不能“显示”,但是Mc是:

def displayable(c):
    return unicodedata.category(c) in {'Mn', 'Me', 'Cc', 'Cf', 'Co', 'Cn'}

但这甚至可能不是您想要的。 例如,不带空格的组合标记后跟一个字母是否算作一个字符或两个字符? 标准示例为U + 0043加U + 0327:两个代码点组成一个字符Ç(但U + 00C7在单个代码点中也是同一字符)。 通常,只要适当地规范化了您的字符串(通常意味着NKFC或NKFD)就足以解决该问题-只要您知道想要什么答案即可。 当然,在您无法回答之前,没有人可以告诉您如何做。


如果您在想“这很糟糕,应该对'printable'的含义进行正式定义,而Python应该知道该定义”,那么,您只需要使用更新版本的Python。 在3.x中,您可以编写:

p = ''.join(c for c in u is c.isprintable())

但是,当然只有在其对“可打印”的定义恰好与您所指的“可显示”含义相匹配时,该方法才有效。 而且也可能不是,例如,他们认为除' '以外' '所有分隔符都是不可打印的。 显然,它们不能包含任何人可能要做出的任何区分的定义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM