本文实例讲述了Python计算字符宽度的方法。分享给大家供大家参考,具体如下:
最近在用python写一个CLI小程序,其中涉及到计算字符宽度,目标是以友好的方式将一个长字符串截取为等宽的片段。
对于unicode字符,python的len函数可以准确的计算其中所包含的字符个数,但是个数并不代表宽度,如:
>>>len(u'你好a') 3
因此无法简单的使用这种方式来计算宽度。
GBK decode
首先我想到GBK编码,00–7F范围内的字符是一字节编码,其余是双字节编码,正好与字符的宽度大体一致,于是有了这样的投机取巧的办法(假设取8个宽度):
>>> a = u'hello你好' >>> b=a.encode('gbk') >>> try: ... print b[:8].decode('gbk') ... except: ... print b[:7].decode('gbk') ... hello你
如代码所示,首先将unicode的字符串进行GBK编码,然后截取8个字节的宽度后尝试用GBK解码,若解码失败,则少截取一个宽度,截取7个字节后使用GBK解码。
虽然初步解决了问题,但是这样做的硬伤很明显。首先代码不优雅,以试错的方式运行;其次GBK所能表示的字符有限,对于大量GBK编码以外的字符无法支持。
East_Asian_Width
徘徊很久之后,偶然发现 Unicode Character Database 标准中有East_Asian_Width 属性,并有以下可能值:
# East_Asian_Width (ea) ea ; A ; Ambiguous 不确定 ea ; F ; Fullwidth 全宽 ea ; H ; Halfwidth 半宽 ea ; N ; Neutral 中性 ea ; Na ; Narrow 窄 ea ; W ; Wide 宽
其中除A不确定外,F/H/N/Na/W都能很明确的知道宽度,如果保守起见,将A视为宽度为2的话,则很容易给出单个字符的宽度:
>>> import unicodedata >>> def chr_width(c): ... if (unicodedata.east_asian_width(c) in ('F','W','A')): ... return 2 ... else: ... return 1 >>> chr_width(u'你') 2 >>> chr_width(u'a') 1
到现在似乎已经可以满足要求了,但是实际使用中发现属性为A的字符真不少见,最典型的就是中文的双引号:
>>> chr_width(u'”') 2
在大多数等宽字体中,中文双引号都是只占一位宽的,如果一行里有多个中文双引号,则累加的误判宽度将会使截取效果大打折扣,无疑这也不是最好的办法。
urwid的解决方案
urwid 是一个成熟的python终端UI库,它在curses的基础之上包装了类似HTML的控件用以显示文本内容,如果有这方面的开发需求,非常推荐此库,比直接使用curses库方便很多,非常棒的是它对unicode的文本宽度截取非常准确,让我大为惊讶,于是翻开它的源码一探究竟,文本宽度计算方面其核心代码如下:
widths = [ (126, 1), (159, 0), (687, 1), (710, 0), (711, 1), (727, 0), (733, 1), (879, 0), (1154, 1), (1161, 0), (4347, 1), (4447, 2), (7467, 1), (7521, 0), (8369, 1), (8426, 0), (9000, 1), (9002, 2), (11021, 1), (12350, 2), (12351, 1), (12438, 2), (12442, 0), (19893, 2), (19967, 1), (55203, 2), (63743, 1), (64106, 2), (65039, 1), (65059, 0), (65131, 2), (65279, 1), (65376, 2), (65500, 1), (65510, 2), (120831, 1), (262141, 2), (1114109, 1), ] def get_width( o ): """Return the screen column width for unicode ordinal o.""" global widths if o == 0xe or o == 0xf: return 0 for num, wid in widths: if o <= num: return wid return 1
如代码所示,首先根据unicode的官方EastAsianWidth 文档整理出字符宽度的范围表,然后使用unicode代码查表。使用之前的例子测试:
>>> get_width(ord(u'a')) 1 >>> get_width(ord(u'你')) 2 >>> get_width(ord(u'”')) 1
完全准确,而且在实际应用中的表现也比较好,是一个理想的解决方案,更多技巧请查阅urwid的old_str_util.py 源码。
更多关于Python相关内容感兴趣的读者可查看本站专题:《Python图片操作技巧总结》、《Python数据结构与算法教程》、《Python Socket编程技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》
希望本文所述对大家Python程序设计有所帮助。

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于Seaborn的相关问题,包括了数据可视化处理的散点图、折线图、条形图等等内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于进程池与进程锁的相关问题,包括进程池的创建模块,进程池函数等等内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于简历筛选的相关问题,包括了定义 ReadDoc 类用以读取 word 文件以及定义 search_word 函数用以筛选的相关内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于数据类型之字符串、数字的相关问题,下面一起来看一下,希望对大家有帮助。

VS Code的确是一款非常热门、有强大用户基础的一款开发工具。本文给大家介绍一下10款高效、好用的插件,能够让原本单薄的VS Code如虎添翼,开发效率顿时提升到一个新的阶段。

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于numpy模块的相关问题,Numpy是Numerical Python extensions的缩写,字面意思是Python数值计算扩展,下面一起来看一下,希望对大家有帮助。

pythn的中文意思是巨蟒、蟒蛇。1989年圣诞节期间,Guido van Rossum在家闲的没事干,为了跟朋友庆祝圣诞节,决定发明一种全新的脚本语言。他很喜欢一个肥皂剧叫Monty Python,所以便把这门语言叫做python。


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft

SublimeText3 Mac version
God-level code editing software (SublimeText3)

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),
