Строка выравнивания по правому краю, содержащая тайские символы
Я хотел бы выровнять строки справа, содержащие тайские символы (тайский рендеринг не работает слева направо, но может также идти вверх и вниз).
Например, для строк ไป (два символа, длина 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 ответа
причина
Тайский сценарий содержит нормальные символы (положительная ширина продвижения) и непропускные метки (нулевая ширина продвижения).
Например, в слове ซื้อ
:
- первый символ - начальная согласная
"SO SO"
, - тогда он имеет гласный знак
SARA UUE
, - затем тон
MAI THO
, - а затем последний псевдо-согласный
O ANG
Проблема в том, что символы ##2 и 3 в списке выше имеют нулевую ширину.
Другими словами, они не делают строку "шире".
Другими словами, ซื้อ
("купить") и ซอ
("скрипка") будет иметь одинаковую ширину из двух символов (но длины строк 4 и 2, соответственно).
Решение
Чтобы вычислить "реальную" длину строки, необходимо пропустить символы нулевой ширины.
Python конкретных
Модуль unicodedata обеспечивает доступ к базе данных символов Unicode (UCD), которая определяет свойства символов для всех символов Unicode. Данные, содержащиеся в этой базе данных, скомпилированы из UCD версии 8.0.0.
unicodedata.category(unichr)
Метод возвращает одно из следующих значений общей категории:
"Lo"
для нормального персонажа;"Mn"
для непропускных меток нулевой ширины;
Остальное очевидно, просто отфильтруйте последние.
Дополнительная информация:
- Данные Unicode для тайского сценария (прокрутите до первого появления "THAI CHARACTER")
Вот функция для вычисления длины тайской строки (количества символов, расположенных по горизонтали) на основе ответа байтебастера
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) символов, составляющих строку.
Я не могу придумать очевидного способа сделать это. Однако я нашел эту библиотеку, которая может быть вам полезна. (Вам также необходимо установить некоторые предварительные условия.