Python处理天城文的经验

天城文(devanagari)是诸多南亚语言的文字,其中最有名的当属梵语。天城文作为婆罗米系元音附标文字,特点鲜明,用编程语言处理时,需掌握如下基本信息:

  • 一共有47个字母,Unicode的区间是U+0900-U+097F,共占据128个码点,可参考Devanagari - Unicode Character Table
  • 其间去除元音的连续的辅音可以按照法则合写在一起为合字(ligature),如त + व = त्व,द् + ध् + र् + य = द्ध्र्य,合写规则非常繁杂
  • Unicode没有为合字分配编码,所以合字的显示应该是靠字体文件中的规则完成的

处理文字无非是处理一段文本或处理单个字符,由于有合写字符,天城文处理起来比汉字更麻烦。

利用正则表达式\X可将一段文本拆成单个的字符,合字会拆分成它所有的组成单元。

1
2
3
4
>>> import regex
>>> sanskrit_text = u"सत्याग्रह"
>>> regex.findall(r'\X', sanskrit_text)
['स', 'त्', 'या', 'ग्', 'र', 'ह']

该单词拆分成了5个字符。从中很容易看出合写规则:त् + या = त्या,ग् + र = ग्र。编辑天城文时会发现,删除一个合字需要按多次键,当删除部分字符时,剩余部分的形态也会根据合写规则发生变化。

但并不是说该单词由5个Unicode字符组成。因为正则表达式\X匹配单个Unicode书写单位(grapheme),该书写单位要么是单个码点(code point),要么是由多个码点构成的组合符号。上面的5个字符中,有的其实是组合而成的,如त् = त + ्,या = य + ा,ग् = ग + ् ,等号后面的才是最基本的符号,每个都对应一个Unicode码点。

要想得到组成该单词的Unicode字符,可以用for语句遍历Unicode字符串,方法如下:

1
2
3
4
5
import unicodedata

sanskrit_text = u"सत्याग्रह"
for c in sanskrit_text:
print(c, c.encode("unicode_escape"), unicodedata.name(c))

得到如下结果:

1
2
3
4
5
6
7
8
9
स b'\\u0938' DEVANAGARI LETTER SA
त b'\\u0924' DEVANAGARI LETTER TA
् b'\\u094d' DEVANAGARI SIGN VIRAMA
य b'\\u092f' DEVANAGARI LETTER YA
ा b'\\u093e' DEVANAGARI VOWEL SIGN AA
ग b'\\u0917' DEVANAGARI LETTER GA
् b'\\u094d' DEVANAGARI SIGN VIRAMA
र b'\\u0930' DEVANAGARI LETTER RA
ह b'\\u0939' DEVANAGARI LETTER HA

一共由9个Unicode字符组成,还附有它们的Unicode编码和描述。里面的VIRAMA符号很常见,感兴趣的可以去了解天城文的书写规则。

参考

  1. python - Combining Devanagari characters - Stack Overflow
  2. unicode - What does the expression match when inside a RegEx? - Stack Overflow