如何在python中使用特殊字符填充和对齐unicode字符串?

时间:2016-05-19 22:27:18

标签: python unicode string-formatting

Python可以轻松填充和对齐ascii字符串,如下所示:

>>> print "%20s and stuff" % ("test")
                test and stuff
>>> print "{:>20} and stuff".format("test")
                test and stuff

但是如何正确填充和对齐包含特殊字符的unicode字符串?我尝试了几种方法,但它们似乎都没有用:

#!/usr/bin/env python
# -*- coding: utf-8 -*- 

def manual(data):
    for s in data:
        size = len(s)
        print ' ' * (20 - size) + s + " stuff"

def with_format(data):
    for s in data:
        print " {:>20} stuff".format(s) 

def with_oldstyle(data):   
    for s in data:
        print "%20s stuff" % (s)

if __name__ == "__main__":
    data = ("xTest1x", "ツTestツ", "♠️ Test ♠️", "~Test2~")
    data_utf8 = map(lambda s: s.decode("utf8"), data)

    print "with_format"
    with_format(data)
    print "with_oldstyle"
    with_oldstyle(data)
    print "with_oldstyle utf8"
    with_oldstyle(data_utf8)
    print "manual:"
    manual(data)
    print "manual utf8:"
    manual(data_utf8)

这提供了不同的输出:

with_format
              xTest1x stuff
           ツTestツ stuff
   ♠️ Test ♠️ stuff
              ~Test2~ stuff
with_oldstyle
             xTest1x stuff
          ツTestツ stuff
  ♠️ Test ♠️ stuff
             ~Test2~ stuff
with_oldstyle utf8
             xTest1x stuff
              ツTestツ stuff
          ♠️ Test ♠️ stuff
             ~Test2~ stuff
manual:
             xTest1x stuff
          ツTestツ stuff
  ♠️ Test ♠️ stuff
             ~Test2~ stuff
manual utf8:
             xTest1x stuff
              ツTestツ stuff
          ♠️ Test ♠️ stuff
             ~Test2~ stuff

这是使用Python 2.7。

1 个答案:

答案 0 :(得分:2)

通过pip可以获得wcwidth个模块。

test.py:

import wcwidth
def manual_wcwidth(data):
    for s in data:
        size = wcwidth.wcswidth(s)
        print ' ' * (20 - size) + s + " stuff"
data = (u"xTest1x", u"ツTestツ", u"♠️ Test ♠️", u"~Test2~")
manual_wcwidth(data)

在linux控制台中,这个脚本为我提供了完美对齐的行:

console screenshot

然而,当我在PyCharm中运行脚本时,带有假名的行仍然移动了一个字符,所以这似乎也依赖于字体和渲染器:

pycharm screenshot