Python UTF-8, как выровнять распечатку - PullRequest
7 голосов
/ 19 марта 2010

У меня есть массив, содержащий японские символы, а также "нормальный". Как выровнять распечатку этих?

#!/usr/bin/python
# coding=utf-8

a1=['する', 'します', 'trazan', 'した', 'しました']
a2=['dipsy', 'laa-laa', 'banarne', 'po', 'tinky winky']

for i,j in zip(a1,a2):
    print i.ljust(12),':',j

print '-'*8

for i,j in zip(a1,a2):
    print i,len(i)
    print j,len(j)

Выход:

する       : dipsy
します    : laa-laa
trazan       : banarne
した       : po
しました : tinky winky
--------
する 6
dipsy 5
します 9
laa-laa 7
trazan 6
banarne 7
した 6
po 2
しました 12
tinky winky 11

спасибо, // Фредрик

Ответы [ 3 ]

4 голосов
/ 19 марта 2010

Используя функцию unicodedata.east_asian_width, отслеживайте, какие символы являются узкими и широкими при вычислении длины строки.

#!/usr/bin/python
# coding=utf-8

import sys
import codecs
import unicodedata

out = codecs.getwriter('utf-8')(sys.stdout)

def width(string):
    return sum(1+(unicodedata.east_asian_width(c) in "WF")
        for c in string)

a1=[u'する', u'します', u'trazan', u'した', u'しました']
a2=[u'dipsy', u'laa-laa', u'banarne', u'po', u'tinky winky']

for i,j in zip(a1,a2):
    out.write('%s %s: %s\n' % (i, ' '*(12-width(i)), j))

Выходы:

する          : dipsy
します        : laa-laa
trazan        : banarne
した          : po
しました      : tinky winky

В некоторых шрифтах веб-браузера он выглядит неправильно, но в окне терминала они правильно выстраиваются.

2 голосов
/ 19 марта 2010

Использовать объекты Unicode вместо байтовых строк:

#!/usr/bin/python
# coding=utf-8

a1=[u'する', u'します', u'trazan', u'した', u'しました']
a2=[u'dipsy', u'laa-laa', u'banarne', u'po', u'tinky winky']

for i,j in zip(a1,a2):
    print i.ljust(12),':',j

print '-'*8

for i,j in zip(a1,a2):
    print i,len(i)
    print j,len(j)

Объекты Unicode имеют дело с символами напрямую.

1 голос
/ 16 марта 2018

Вам необходимо вручную построить строку, а также вручную построить длину формата.Для этого нет простого способа

Три функции, перечисленные ниже, делают это (требуется unicodedata):

shortenStringCJK: правильно сокращать до длины для подгонки в некоторых выходных данных (без сокращения длины для получения символов X))

def shortenStringCJK(string, width, placeholder='..'):
# get the length with double byte charactes
string_len_cjk = stringLenCJK(str(string))
# if double byte width is too big
if string_len_cjk > width:
    # set current length and output string
    cur_len = 0
    out_string = ''
    # loop through each character
    for char in str(string):
        # set the current length if we add the character
        cur_len += 2 if unicodedata.east_asian_width(char) in "WF" else 1
        # if the new length is smaller than the output length to shorten too add the char
        if cur_len <= (width - len(placeholder)):
            out_string += char
    # return string with new width and placeholder
    return "{}{}".format(out_string, placeholder)
else:
    return str(string)

stringLenCJK: получить правильную длину (как в пространстве, занимаемом терминалом)

def stringLenCJK(string):
    # return string len including double count for double width characters
    return sum(1 + (unicodedata.east_asian_width(c) in "WF") for c in string)

formatLen: отформатировать длину, чтобы настроить ширину из двухбайтовых символов.без этого длина будет несбалансированной.

def formatLen(string, length):
    # returns length udpated for string with double byte characters
    # get string length normal, get string length including double byte characters
    # then subtract that from the original length
    return length - (stringLenCJK(string) - len(string))

для вывода некоторой строки: предварительно определите строку формата

format_str = "|{{:<{len}}}|"
format_len = 26
string_len = 26

и выведите ее следующим образом (где _string - строка для вывода)

print("Normal : {}".format(
    format_str.format(
        len=formatLen(shortenStringCJK(_string, width=string_len), format_len))
    ).format(
        shortenStringCJK(_string, width=string_len)
    )
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...