如何在Python中生成gettext复数形式表达的示例?

1 投票
1 回答
1849 浏览
提问于 2025-04-15 11:07

给定一个gettext的复数形式行,我想为每个n生成一些示例值。我希望这个功能能在我网站的翻译者的网页界面上使用,这样他们就知道在什么地方放哪个复数形式。例如,给定:

"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" "10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"

... 我希望第一个文本框标记为 "1, 21..",然后是 "2, 3, 4...",接着是 "5, 6..."(不确定这是否完全正确,但你明白我的意思)。

现在我能想到的最好办法是以某种方式解析这个表达式,然后让x从0循环到100,看看它产生了什么n。这并不能保证一定有效(如果某种语言的最低x超过100怎么办?)但可能已经足够好了。有没有更好的想法或者现成的Python代码?

1 个回答

1

既然已经很晚了,我就来试试吧。

下面这个解决方案有点儿 hacky(不太正规),它的做法是把你的复数形式转换成可以在 Python 中运行的代码(基本上就是把 x ? y : z 这样的语句转换成 Python 中的 x and y or z 形式,同时把 && 和 || 换成 and 和 or)。

我不太确定你的复数形式规则是不是个特例,而且我也不太明白你第一段文本的意思,不过我相信你能理解我这个示例解决方案的思路:

# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4

p = "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"

# extract rule
import re
matcher = re.compile('plural=(.*);')
match = matcher.search(p)
rule = match.expand("\\1")

# convert rule to python syntax
oldrule = None
while oldrule != rule:
    oldrule = rule
    rule = re.sub('(.*)\?(.*):(.*)', r'(\1) and (\2) or (\3)', oldrule)

rule = re.sub('&&', 'and', rule)
rule = re.sub('\|\|', 'or', rule)

for n in range(40):
    code = "n = %d" % n
    print n, eval(rule)

撰写回答