【Python】字符串显示宽度计算的方法
创始人
2024-05-13 17:42:57
0

字符串显示宽度计算的方法

文章目录

  • 字符串显示宽度计算的方法
    • 1. 缘起
    • 2. 研究方向
    • 3. 核心内容
      • 3.1 什么是`East Asian Width`
      • 3.2 使用案例
        • 3.2.1 六种文字分类的分别举例输出
        • 3.2.2 `unicodedata.east_asian_width`常见错误
      • 3.3 实际应用
      • 3.4 注意事项

1. 缘起

最近两天要给公司的小朋友写个工具,需要在控制台输出一些信息。 开始以为是一件简单的事情。 但是谁让田老师是处女座呢,追求完美不是。

如果要在终端输出格式的信息,计算字符串的显示宽度就是必要的事情。 但是对与这个看似简单的功能,Python的len()函数并不能有效的解决这个问题,只能自己研究了。 (多么怀念VB里面的LenB()函数啊。)

2. 研究方向

既然len()函数无法解决中文的显示长度问题。 那么只能使用标准库unicodedata中的east_asian_width()函数来解决问题。这个函数可以根据给到的unicode字符的值,判断是半角还是全角。

找了一下中文互联网上的资料,还没有文章把这个问题说透。 所以写成此文记录之。

3. 核心内容

这里主要要说明3个问题:

  • East Asian Width 这个概念
  • unicodedata.east_asian_width() 函数的基本使用(不只是中文)
  • 实际使用案例
  • 注意事项

3.1 什么是East Asian Width

“东亚字符宽度”是 Unicode 标准附件之一。 它定义了East_Asian_Width参考特征,该特征提供有关 Unicode 中每个字符的字符宽度的提示。

East Asian Width(东亚字符宽度)这个概念被定义是在《Unicode® 标准附录 #11》中。 链接为:UAX #11:东亚宽度 (unicode.org)

对于东亚语言来说,主要是固定间距字体。 要处理的内容包括半角英数字、正常的汉字、半角显示的特殊字符,以及从日语shift-jis编码过来的颜文字等各种特殊字符。

以田老师的项目经验,中文在此方面还算是相对简单的。 中等复杂的是日语,既有类似与中文的“日语汉字”、平假名(あいうえお)、片假名(アイウエオ)、还有小子表示的片假名(アイウエオ)。 当然,最复杂的还要数西里尔语言体系、阿拉伯语、希腊语方面的应用。

Python通过unicodedata.east_asian_width()通过6种分类,给出每一个unicode字符的宽度。这六种分类分别是:

  • F(全角) - 全角字母数字等。
  • H(半角) - 所谓的半角假名(アイウエオ)等。
  • W(宽) - 上述字符以外的字符,在传统字符代码中称为全角字符。 汉字、日语假名字符和描述符号(例如标点符号),这些符号仅用于东亚的组版本。
  • Na(窄) - 上述字符以外的字符,在传统字符代码中存在相应的所谓全角字符。 所谓的半角字母数字等。
  • A(模糊) - 字符宽度因上下文而异的字符。 它甚至不能用简单的中文和日语的全半角去理解。 比如希腊语、西里尔文等。 在东亚的传统字符代码中可以被视为所谓的全角。
  • N(中性) - 不属于上述任何字符的字符。 它通常不出现在东亚的组版本中,也不是全角的或半角的。 阿拉伯字母等。

3.2 使用案例

3.2.1 六种文字分类的分别举例输出

import unicodedataif __name__ == "__main__":print(unicodedata.east_asian_width('A'))  # 全角字母Aprint(unicodedata.east_asian_width('ア'))  # 日语半角假名print(unicodedata.east_asian_width('田'))  # 汉字‘田’print(unicodedata.east_asian_width('k'))  # 英语字母kprint(unicodedata.east_asian_width('Б'))  # 西里尔语系,俄语字母Бprint(unicodedata.east_asian_width('ل'))  # 阿拉伯语ل

输出结果

D:\Python-grp\miniconda3_data\env\py3.10\python.exe E:\develop\python\pystudy\src\unicode_east_asian_width.py 
F
H
W
Na
A
N进程已结束,退出代码0

3.2.2 unicodedata.east_asian_width常见错误

本函数的常见错误,就是输入的是字符串而不是字符。比如:

>>> import unicodedata
>>> unicodedata.east_asian_width('田辛')
Traceback (most recent call last):File "", line 1, in 
TypeError: east_asian_width() argument must be a unicode character, not str
>>> unicodedata.east_asian_width('田')
'W'
>>> unicodedata.east_asian_width('辛')
'W'
>>>

3.3 实际应用

def get_east_asian_width_count(text):count = 0for c in text:if unicodedata.east_asian_width(c) in 'FWA':count += 2else:count += 1return count

函数调用

if __name__ == "__main__":print(get_east_asian_width_count('田辛'))print(get_east_asian_width_count('pythonとは?'))print(get_east_asian_width_count('1234567890'))

输出结果

D:\Python-grp\miniconda3_data\env\py3.10\python.exe E:\develop\python\pystudy\src\unicode_east_asian_width.py 
4
12
10进程已结束,退出代码0

3.4 注意事项

因为项目经验有限,本文在处理中文,基本日文语言中没有问题。 涉及到俄文、阿拉伯语项目可能还有不足之处。当然UAX #11: East Asian Width (unicode.org)的原始作者小林剣本人也承认这一点。

相关内容

热门资讯

银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...