簡體   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