右对齐包含泰语字符的字符串

Posted

技术标签:

【中文标题】右对齐包含泰语字符的字符串【英文标题】:Right justify string containing Thai characters 【发布时间】:2012-11-29 20:02:25 【问题描述】:

我想(泰语渲染不能从左到右工作,但也可以上下)。

例如,对于字符串 ไป(两个字符,长度为 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 个位置。

【问题讨论】:

您使用的是什么语言/环境? 不清楚这个问题是关于什么软件/语言/环境的。 看起来很漂亮。 import antigravity - 这是 Python。 语言、环境?我在 MacBook Air 上,Python 2.7……是那种环境吗? 【参考方案1】:

原因

泰语脚本包含普通字符(正向宽度)和非间距标记(零高级宽度)。

例如在ซื้อ这个词中:

    第一个字符是声母"SO SO", 那么它有元音标记 SARA UUE, 然后音标MAI THO, 然后是最后的伪辅音O ANG

问题是上面列表中的字符##2 和 3 是零宽度的。 换句话说,它们不会使字符串“更宽”。 换句话说,ซื้อ ("to buy") 和 ซอ ("fiddle") 两个字符位置的宽度相等(但字符串长度分别为 4 和 2)。

解决方案

为了计算“真正的”字符串长度,必须跳过零宽度字符。

Python 特定

unicodedata 模块提供对 Unicode 字符数据库 (UCD) 的访问,该数据库定义了所有 Unicode 字符的字符属性。此数据库中包含的数据是从 UCD 版本 8.0.0 编译而来的。

unicodedata.category(unichr) 方法returns 下列General Category Values 之一:

"Lo" 普通字符; "Mn" 用于零宽度非间距标记;

剩下的就很明显了,把后面的过滤掉就行了。


更多信息:

Unicode data for Thai script(滚动到第一次出现“泰语字符”)

【讨论】:

【参考方案2】:

我认为您要问的是,如何确定 เรือ、ไป、ซื้อ 等(分别为 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 的角度)字符数之间没有真正的相关性。

我想不出一个明显的方法来做到这一点。但是,我发现 this library 可能对您有所帮助。 (您还需要安装一些prequisites。

【讨论】:

谢谢,阿努杰古普塔。阅读建议的库函数,我不清楚它们是否适用于泰语;他们的重点是东亚语言。我想,我只是通过对相应的unicode表示进行分类来自己实现这样一个真实长度的函数。【参考方案3】:

看起来 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++

【讨论】:

【参考方案4】:

根据 bytebuster 的回答,这是一个计算泰语字符串长度(水平排列的字符数)的函数

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('บอินทัช'))

【讨论】:

以上是关于右对齐包含泰语字符的字符串的主要内容,如果未能解决你的问题,请参考以下文章

格式化输出字符串,右对齐

如何在Objective C中使用XML解析发布带有特殊字符和泰语的字符串?

Java中的右对齐字符串NumberFormat

Python:固定长度字符串左/右对齐多个变量

输出的字符靠右对齐

我如何检查字符串是返回布尔值的泰语,如 isalpha()