2016-05-19 12 views
8

Python ułatwia pad i wyrównać ciągi ASCII, tak jak poniżej:Jak nakładać i wyrównywać ciągi znaków Unicode za pomocą znaków specjalnych w pythonie?

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

Ale jak mogę poprawnie pad oraz dostosowanie napisów Unicode, zawierających znaki specjalne? Próbowałem kilka sposobów, ale żaden z nich nie wydają się działać:

#!/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) 

Daje urozmaicone wyjściowe:

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 

to przy użyciu Python 2.7.

+2

Myślę, że 'data_utf8' lepiej zmienić nazwę na" data_unicode ", ponieważ zawiera to drugie. – robyschek

+1

to może być związane z tym pytaniem: http://stackoverflow.com/questions/4622357/how-to-control-padding-of-unicode-string-containing-east-asia-charicles –

+1

Możesz być zainteresowany Unicode Standardowa koncepcja ["grupy grafemów"] (http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries), która z grubsza odpowiada postaciom odbieranym przez użytkownika czytającego fragment tekstu i modułom stron trzecich do obliczeń klastry grafem, takie jak ['uniseg.graphemecluster'] (http://uniseg-python.readthedocs.io/en/latest/graphemecluster.html). Możliwe, że będziesz potrzebował dodatkowej obsługi dla znaków o zerowej szerokości i oczywiście dla czcionek o stałej szerokości, dopełnienie będzie działać inaczej. – user2357112

Odpowiedz

2

Dostępny jest moduł wcwidth za pośrednictwem pip.

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) 

W konsoli Linux Ten skrypt przynosi dla mnie idealnie wyrównane linie:

console screenshot

Jednak kiedy uruchomić skrypt w pycharm linię z kana jest wciąż przesunięto jeden znak w lewo, więc wydaje się, że zależy to również od czcionki i renderera:

pycharm screenshot

+0

Działa to dobrze dla naszych celów (używamy terminalu OS X do wyświetlania tekstu). Dzięki za wskazówkę! Należy pamiętać, że wymaga to "pip install wcwidth" – camomilk

+0

Japońskie i chińskie znaki są znakami o pełnej szerokości i są nieco szersze niż inne znaki w większości (wszystkich?) Czcionek. Około 3 znaki o pełnej szerokości to 4 zwykłe znaki, więc tylko posiadanie dwóch w ciągu powoduje nieznaczne wyrównanie z powodu zaokrąglenia. –

Powiązane problemy