例如 a = 'PM2.5' b = '地下管道' c = '空铁 WIFI',a 、b 、c 的宽度分别为 5 、8 、8,字母、数字的宽度为 1,汉字的宽度为 2 。用 len 函数得到的结果为 5 、4 、6 ;用 sys.getsizeof 得到的结果为 54 、82 、86,当字符串中含有混合字符时也不能用来推导显示宽度。请教还有没有其他方法。
1
codehz 2020-05-17 14:35:45 +08:00
用 freetype 的 api 真实可以取得各种测量属性,当然,需要指定字体
|
2
xcstream 2020-05-17 14:43:09 +08:00
用等宽字体 判断中英文
|
3
ClericPy 2020-05-17 14:50:22 +08:00
暂时能想到的就只有正则出中文字数... len + len_中
|
4
secondwtq 2020-05-17 14:53:20 +08:00
这么复杂的问题你确定能在中文社区问出答案来么……
|
5
0x5f 2020-05-17 15:04:03 +08:00 1
如果是获取显示在图片上的宽度话 pil 库里有个 ImageFont.getsize()可以返回渲染后文字长宽
|
6
JCZ2MkKb5S8ZX9pq 2020-05-17 15:52:43 +08:00 1
我自己在用的是这个
width = (len(string) + len(string.encode('utf-8'))) // 2 # py3 前置还要移掉点 anis 之类的玩意儿,中日英目前用下来还好,日文小字也算 2 。 但是类似西班牙语法语那种带小尾巴的,unicode 有种写法是尾巴单独用一个字符,那个也许会有问题。 |
7
JCZ2MkKb5S8ZX9pq 2020-05-17 15:56:55 +08:00
|
8
lithbitren 2020-05-17 15:59:44 +08:00
只看中英文和常用符号还好,加上其他语言符号是真 jb 复杂
|
9
JCZ2MkKb5S8ZX9pq 2020-05-17 16:03:25 +08:00
另外我上面说的都是我在程序里打印结果,然是是等宽字体的情况下的占位数。
如果是显示的话,要看显示在什么地方,以及用什么字体吧。lz 可以把问题再具体一点。 图片的话上面提到 pil 可以,截屏去拿也是个办法。 终端的话因为是等宽的,且行宽可测所以推测行数也是可以的。 |
10
justfortest 2020-05-17 18:05:35 +08:00 via Android
这是个复杂的问题
|
11
jin7 2020-05-17 19:13:23 +08:00
用 pyqt5/pyside2 就行了 很容易计算宽度
|
12
XIVN1987 2020-05-17 21:56:35 +08:00 1
In [11]: s = '空铁 WIFI'
In [12]: [ord(c) for c in s] Out[12]: [31354, 38081, 87, 73, 70, 73] In [13]: [1 if ord(c) < 0x80 else 2 for c in s] Out[13]: [2, 2, 1, 1, 1, 1] In [14]: sum([1 if ord(c) < 0x80 else 2 for c in s]) Out[14]: 8 |
13
lithbitren 2020-05-17 22:06:14 +08:00
全角和半角符号的编码范围不是连续的,一个比较符的实现可能还是有 bug 的。
|
14
Kisesy 2020-05-17 22:12:58 +08:00
if unicodedata.east_asian_width(char) in ('F', 'W'):
width = width + 2 else: width = width + 1 |
15
XiaoxiaoPu 2020-05-17 22:28:12 +08:00
有个现成的库,用了很久了 wcwidth
|
16
aihimmel 2020-05-17 22:44:15 +08:00 via Android
不要简单推定字符宽度
"لا" 上面这个是两个字符但是打印出来只有 1 的宽度,确定宽度最好还是渲染出来再取宽度 |
18
songdg OP @JCZ2MkKb5S8ZX9pq 谢谢,基本上解决了我的问题。
|
21
HashV2 2020-05-20 17:54:26 +08:00
@JCZ2MkKb5S8ZX9pq 哈哈哈哈 我用的也是这个,但确实不太优雅哈~
|