Строка выравнивания по правому краю, содержащая тайские символы

Я хотел бы выровнять строки справа, содержащие тайские символы (тайский рендеринг не работает слева направо, но может также идти вверх и вниз).

Например, для строк ไป (два символа, длина 2) и ซื้อ (четыре символа, длина 2) я хочу получить следующий вывод (длина 5):

...ไป

...ซื้อ

Наивный

print 'ไป'.decode('utf-8').rjust(5)

print 'ซื้อ'.decode('utf-8').rjust(5)

однако соответственно производят

...ไป

.ซื้อ

Есть идеи как добраться до нужного форматирования?

РЕДАКТИРОВАТЬ: Учитывая строку тайских символов tc, я хочу определить, сколько [мест / полей / позиций / как вы хотите это назвать] использует строка. Это не то же самое, что len(tc); len(tc) обычно больше, чем количество используемых мест. Второе слово дает len(tc) = 4, но имеет длину 2 / использует 2 места / использует 2 позиции.

3 ответа

причина

Тайский сценарий содержит нормальные символы (положительная ширина продвижения) и непропускные метки (нулевая ширина продвижения).

Например, в слове ซื้อ:

  1. первый символ - начальная согласная "SO SO",
  2. тогда он имеет гласный знак SARA UUE,
  3. затем тон MAI THO,
  4. а затем последний псевдо-согласный O ANG

Проблема в том, что символы ##2 и 3 в списке выше имеют нулевую ширину.
Другими словами, они не делают строку "шире".
Другими словами, ซื้อ ("купить") и ซอ ("скрипка") будет иметь одинаковую ширину из двух символов (но длины строк 4 и 2, соответственно).

Решение

Чтобы вычислить "реальную" длину строки, необходимо пропустить символы нулевой ширины.

Python конкретных

Модуль unicodedata обеспечивает доступ к базе данных символов Unicode (UCD), которая определяет свойства символов для всех символов Unicode. Данные, содержащиеся в этой базе данных, скомпилированы из UCD версии 8.0.0.

unicodedata.category(unichr) Метод возвращает одно из следующих значений общей категории:

  • "Lo" для нормального персонажа;
  • "Mn" для непропускных меток нулевой ширины;

Остальное очевидно, просто отфильтруйте последние.


Дополнительная информация:

Вот функция для вычисления длины тайской строки (количества символов, расположенных по горизонтали) на основе ответа байтебастера

import unicodedata


def get_thai_string_length(string):
    length = 0
    for c in string:
        if unicodedata.category(c) != 'Mn':
            length += 1
    return length

print(len('บอินทัช'))
print(get_thai_string_length('บอินทัช'))

Похоже, что функция rjust() не будет работать для вас, и вам нужно будет самостоятельно подсчитать количество ячеек в строке. Затем вы можете вставить количество пробелов, необходимых перед строкой, чтобы добиться выравнивания

Вы, кажется, знаете о тайском языке. Суммируйте количество согласных, предшествующих гласных, следующих гласных и тайской пунктуации. Не считайте диакритические знаки и гласные выше и ниже.

Что-то вроде (простите мой псевдо-код Python),

cells = 0

for i in range (0, len(string))
  if (string[i] == \xe31) or ((string[i] >= \xe34) and (string[i] <= \xe3a)) or ((string[i] >= \xe47) and (string[i] <= \xe4e))
     # do nothing
  else
     # consonant, preceding or following vowel or punctuation
     cells++

Я думаю, что вы хотите спросить, как определить "истинное" количество символов в เรือ, ไป, ซื้อ и т. Д. (Которые составляют 3,2 и 2, соответственно)

К сожалению, вот как Python интерпретирует эти символы:

ไป

>>> 'ไป'
'\xe0\xb9\x84\xe0\xb8\x9b'
>>> len('ไป')
6
>>> len('ไป'.decode('utf-8'))
2

ซื้อ

>>> 'ซื้อ'
'\xe0\xb8\x8b\xe0\xb8\xb7\xe0\xb9\x89\xe0\xb8\xad'
>>> len('ซื้อ')
12
>>> len('ซื้อ'.decode('utf-8'))
4

เรือ

>>> 'เรือ'
'\xe0\xb9\x80\xe0\xb8\xa3\xe0\xb8\xb7\xe0\xb8\xad'

>>> len('เรือ')
12
>>> len('เรือ'.decode('utf-8'))
4

Нет реальной корреляции между количеством отображаемых символов и количеством фактических (с точки зрения Python) символов, составляющих строку.

Я не могу придумать очевидного способа сделать это. Однако я нашел эту библиотеку, которая может быть вам полезна. (Вам также необходимо установить некоторые предварительные условия.

Другие вопросы по тегам