Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >格式化包含非ascii字符的列

格式化包含非ascii字符的列
EN

Stack Overflow用户
提问于 2016-01-07 04:38:38
回答 2查看 910关注 0票数 10

所以我想对齐包含非ascii字符的字段。以下几点似乎不起作用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for word1, word2 in [['hello', 'world'], ['こんにちは', '世界']]:
    print "{:<20} {:<20}".format(word1, word2)

hello                world
こんにちは      世界

有解决办法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-07 04:47:45

您正在格式化多字节编码的字符串。您似乎正在使用UTF-8对您的文本进行编码,而且编码每个代码点使用多个字节(根据具体字符的不同,在1到4之间)。格式化字符串会计算字节,而不是代码点,这也是字符串最终对齐错误的原因之一:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> len('hello')
5
>>> len('こんにちは')
15
>>> len(u'こんにちは')
5

将文本格式化为Unicode字符串,以便您可以计数代码点,而不是字节:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for word1, word2 in [[u'hello', u'world'], [u'こんにちは', u'世界']]:
    print u"{:<20} {:<20}".format(word1, word2)

您的下一个问题是,这些字符也比大多数字符更宽;您有两个范围的代码点:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> import unicodedata
>>> unicodedata.east_asian_width(u'h')
'Na'
>>> unicodedata.east_asian_width(u'世')
'W'
>>> for word1, word2 in [[u'hello', u'world'], [u'こんにちは', u'世界']]:
...     print u"{:<20} {:<20}".format(word1, word2)
...
hello                world
こんにちは                世界

str.format()不具备处理这个问题的能力;在格式化之前,您必须根据在Unicode标准中注册为更宽的字符数量来手动调整列宽。

这很棘手,因为有一个以上的宽度可用。查看Unicode标准附件;有窄的、宽的和的双倍宽度;窄是大多数其他字符打印的宽度,宽是我终端上的两倍。暧昧是..。对于实际显示的宽度不明确:

含糊不清的字符需要字符代码中没有包含的其他信息来进一步解析它们的宽度。

这取决于上下文的显示方式;例如,希腊字符在西方文本中显示为狭窄字符,而在东亚上下文中则显示为宽字符。我的终端显示它们很窄,但其他终端(例如,为东亚地区配置的)可能会显示它们的宽度。我不确定是否有任何防止愚昧的方法来弄清楚那是怎么回事。

在大多数情况下,您需要将带有'W''F'值的字符计数为unicodedata.east_asian_width(),作为两个位置;从格式宽度中减去1:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def calc_width(target, text):
    return target - sum(unicodedata.east_asian_width(c) in 'WF' for c in text)

for word1, word2 in [[u'hello', u'world'], [u'こんにちは', u'世界']]:
    print u"{0:<{1}} {2:<{3}}".format(word1, calc_width(20, word1), word2, calc_width(20,  word2))

这将在我的终端中产生所需的对齐。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> for word1, word2 in [[u'hello', u'world'], [u'こんにちは', u'世界']]:
...     print u"{0:<{1}} {2:<{3}}".format(word1, calc_width(20, word1), word2, calc_width(20,  word2))
...
hello                world
こんにちは           世界

您可能在上面看到的轻微的不对齐是您的浏览器或字体使用不同的宽度比(不是很大的两倍)为宽码点。

所有这些都附带了一个警告:并不是所有的终端都支持东亚宽度Unicode属性,并且只在一个宽度上显示所有代码点。

票数 8
EN

Stack Overflow用户

发布于 2016-01-07 04:59:12

这不是一项简单的任务--这不是简单的“非ascii”--它们是宽unicode字符,它们的显示非常棘手--从根本上讲,这更多地取决于您使用的终端类型,而不是您在其中放置的空格数。

首先,您必须使用UNICODE字符串。由于您在Python 2中,这意味着您应该在文本引号前加上"u“。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for word1, word2 in [[u'hello', u'world'], [u'こんにちは', u'世界']]:
    print "{:<20} {:<20}".format(word1, word2)

这样,Python实际上可以将字符串中的每个字符识别为一个字符,而不是一个字节集合,这些字节由于偶然的原因而被显示出来。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> a = u'こんにちは'
>>> len(a)
5
>>> b = 'こんにちは'
>>> len(b)
15

乍一看,这些长度似乎可以用来计算字符宽度。不幸的是,utf-8编码字符的字节长度与字符的实际显示宽度无关。单宽度unicode字符也是utf-8中的多字节字符(如ç)。

现在,在讨论unicode之后,Python确实包含了一些实用工具--包括一个函数调用,以了解每个unicode的显示单元是什么--字符--它是unicode.east_asian_width --这允许您有一种方法来计算每个字符串的宽度,然后有适当的空格数:

自动计算“{:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import unicode

def display_len(text):
    res = 0
    for char in text:
        res += 2 if unicodedata.east_asian_width(char) == 'W' else 1
    return res

for word1, word2 in [[u'hello', u'world'], [u'こんにちは', u'世界']]:
    width_format = u"{{}}{}{{}}".format(" " * (20 - (display_len(word1))))
    print width_format.format(word1, word2)

在我的终端机上对我起了作用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
hello              world
こんにちは          世界

但正如Martijn所说,它比这更复杂。有歧义字符和终端类型。如果您确实需要在文本终端中对齐这个文本,那么您应该使用终端库,比如诅咒,它允许您指定一个显示坐标来打印字符串。这样,在打印每个单词之前,您可以简单地在适当的列上明确地定位光标,并避免所有显示宽度的计算。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34655347

复制
相关文章
删除列中的 NULL 值
今天接到一个群友的需求,有一张表的数据如图 1,他希望能通过 SQL 查询出图 2 的结果。
白日梦想家
2020/07/20
9.9K0
删除列中的 NULL 值
访问列表中的值
#!/usr/bin/python list1 = ['physics', 'chemistry', 1997, 2000] list2 = [1, 2, 3, 4, 5, 6, 7 ] print "list1[0]: ", list1[0] print "list2[1:5]: ", list2[1:5]
用户8442333
2021/05/27
5.6K0
B+树索引使用(7)匹配列前缀,匹配值范围(十九)
上篇文章索引的代价,b+树占的空间比较大,增删改对b+树每个节点的索引排序影响也很大,时间耗费长,所以没有必要不要乱建索引,还介绍了索引的最左原则和全值查询。
用户9919783
2022/07/26
9950
【说站】Python如何在列表中添加新值
1、append()将元素添加到集合,insert()将元素插入指定的下标应用程序,返回值为None。
很酷的站长
2022/11/24
4.1K0
【说站】Python如何在列表中添加新值
【说站】Python DataFrame如何根据列值选择行
以上就是Python DataFrame根据列值选择行的方法,希望对大家有所帮助。
很酷的站长
2022/11/24
5.3K0
【说站】Python DataFrame如何根据列值选择行
获取GridView中的某列值
    protected void GridView1_RowEditing(object sen
Java架构师必看
2021/03/22
10.2K0
如何使用Excel将某几列有值的标题显示到新列中
如果我们有好几列有内容,而我们希望在新列中将有内容的列的标题显示出来,那么我们怎么做呢?
繁华是客
2023/03/03
11.3K0
Excel应用实践19:根据工作表某列中的值从另一工作簿中获取数据
在下图1所示的工作簿Data.xlsx的工作表Sheet1中,存放着待使用的数据。
fanjy
2019/08/27
18.9K0
Excel应用实践19:根据工作表某列中的值从另一工作簿中获取数据
根据数据源字段动态设置报表中的列数量以及列宽度
在报表系统中,我们通常会有这样的需求,就是由用户来决定报表中需要显示的数据,比如数据源中共有八列数据,用户可以自己选择在报表中显示哪些列,并且能够自动调整列的宽度,已铺满整个页面。本文就讲解一下Act
葡萄城控件
2018/01/10
4.9K0
根据数据源字段动态设置报表中的列数量以及列宽度
Zabbix 值匹配字符串 创建触发器
Zabbix监控脚本返回值是字符串时,也可以使用字符串函数来创建触发器。举个栗子,现在有个需求要监控从服务器上下载数据是否出现异常,当数据下载失败时返回异常并告警。那么就可以在监控脚本中设置当下载成功时返回值为”download complete”,下载失败时返回值为异常信息。 创建监控项时设置返回值为字符型。
我是李超人
2020/08/20
1.2K0
python中创建列表的方法_python中readlines
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/184390.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/27
3.8K0
在数据框架中创建计算列
在Excel中,我们可以通过先在单元格中编写公式,然后向下拖动列来创建计算列。在PowerQuery中,还可以添加“自定义列”并输入公式。在Python中,我们创建计算列的方式与PQ中非常相似,创建一列,计算将应用于这整个列,而不是像Excel中的“下拉”方法那样逐行进行。要创建计算列,步骤一般是:先创建列,然后为其指定计算。
fanjy
2022/04/13
3.8K0
在数据框架中创建计算列
【Redis】Redis 列表 List 操作 ( 查询操作 | 根据下标获取元素 | 获取列表长度 | 增操作 | 插入值 | 删操作 | 移除值 | 修改操作 | 设置列表指定索引的值 )
在 Redis 中 , 通过 一个 键 Key , 可以 存储多个值 , 这些值存放在一个 List 列表中 ;
韩曙亮
2023/03/30
6.4K0
【Redis】Redis 列表 List 操作 ( 查询操作 | 根据下标获取元素 | 获取列表长度 | 增操作 | 插入值 | 删操作 | 移除值 | 修改操作 | 设置列表指定索引的值 )
列表:创建列表
列表是Tcl语言中最重要的一种数据结构。什么是列表?列表是元素的有序集合,各个元素可以包含任何字符串,例如空格,反斜杠,换行符等。列表表现为特定结构的字符串,这意味着可以把它们赋值给一个变量,可以把它们做为参数传给命令,可以把它们嵌套到其他列表中。
Lauren的FPGA
2019/10/30
2.4K0
HBase 根据表名与列信息与配置信息创建表
private static Configuration configuration=null; static{ configuration= HBaseConfigurati
爱明依
2019/03/12
9280
Pandas 查找,丢弃列值唯一的列
数据清洗很重要,本文演示如何使用 Python Pandas 来查找和丢弃 DataFrame 中列值唯一的列,简言之,就是某列的数值除空值外,全都是一样的,比如:全0,全1,或者全部都是一样的字符串如:已支付,已支付,已支付…
萝 卜
2022/05/12
5.7K0
Pandas 查找,丢弃列值唯一的列
Mysql与Oracle中修改列的默认值
背景: 业务发展需要,需要复用历史的表,并且通过表里面原来一个未使用的字段来区分不同的业务。 于是想到通过default来修改列的默认值: alter table A modify column biz default 'old' comment '业务标识 old-老业务, new-新业务' 现象: 上线几天之后,业务反馈旧业务的相关数据查询不到了。找后台运维查生产数据库,发现历史数据的biz字段还是null 原因: 自己在本地mysql数据库试了下,好像的确是default没法修改历史数据为null
SecondWorld
2021/09/08
13.2K0
Ext根据条件显示隐藏列
  写在ExtonReady函数里面,并在表格成功渲染之后,可以添加判断是否隐藏或者显示某一列
河岸飞流
2019/08/09
2.7K0
Sql Server 中 根据具体的值 查找该值所在的表和字段
在我们的工作中经常遇到这样一个问题,在页面中保存一条数据,有个字段值为“张三”,但是,不知道这条数据保存在了哪个表中,现在我们想要追踪该值是存储到了那个表的那个字段中,具体要怎么操作呢?下面我们可以借助存储过程来解决这一问题
jamesjiang
2022/11/20
6.4K0
Sql Server 中 根据具体的值 查找该值所在的表和字段
点击加载更多

相似问题

匹配Pandas列中的单词,并根据匹配创建新列

30

根据列表中的匹配项创建列

214

根据其他列中的值创建新列

28

如何根据diff列中的值创建具有列表中可用值的新列?

16

是否根据其他pandas列的列表中的值数创建新列?

20
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文