我正在对字符和单词使用 ICU 的中断迭代器,如here中所述。我预计字符分隔迭代器的输出会更频繁地停止,并且断点是分词迭代器的超集。例如,如果我通过
abc
,我会从字符中断迭代器中获得 a
、b
和 c
,同时从分词迭代器中获得 abc
。
现在,我有一个泰语字符串作为
ด้าน้ำ
。问题在于这两个中断迭代器的行为不一致。鉴于上述字符串的长度在 Unicode 中为 6,我从 MacOS 上的 ICU 61.1 得到以下结果:
Word boundaries:
[0, 5)
[5, 6)
Character boundaries:
[0, 2)
[2, 3)
[3, 6)
如您所见,字符中断运算符会中断
[3, 6)
中的单词(这似乎是正确的),而单词中断运算符会中断 [5, 6)
中的单词。这是一个小的 Python3 代码,它使用 PyICU 来重现该问题:
import PyICU
def wordBreakIterator():
return PyICU.BreakIterator.createWordInstance(PyICU.Locale("th"))
def charBreakIterator():
return PyICU.BreakIterator.createCharacterInstance(PyICU.Locale("th"))
def printBoundaries(txt, bi):
bi.setText(txt)
start = bi.first()
try:
while True:
end = next(bi)
print("[{}, {})".format(start, end))
start = end
except StopIteration:
pass
if __name__ == "__main__":
text = u'ด้าน้ำ'
print("Word boundaries:")
printBoundaries(text, wordBreakIterator())
print("Character boundaries:")
printBoundaries(text, charBreakIterator())
我正在实施技术报告#29中的规则,它定义了如何确定用户感知的字符(也称为字素簇)、单词和句子边界。规则集不是相互构建的,而是完全独立定义的。例如,这意味着单词不是通过迭代字素簇来定义的,而是单独通过底层代码点来定义的。每个规则集还有其自己单独的数据表集。因此,有时它们与您发现的不匹配。 应用当前的Unicode 15.1规则和数据表,字符跨度不变,单词跨度为:
(0, 2)
(2, 3)
(3, 5)
(5, 6)
在单词边界规则对于泰语、老挝语、高棉语、缅甸语和其他通常不在单词之间使用空格的脚本,良好的实现不应依赖于默认的单词边界规范。
你需要这样做!