我需要合并/更新/删除 .po 文件消息并需要一些 Python 包,它允许我完全解析 .po 文件,包括:消息、复数、位置、上下文和注释。
我想做一个简单的工具来检查文件之间的差异。我也可以使用一些已经完成的 GUI,但不确定是否有这样的工具会添加新的翻译或删除未使用的翻译。
我正在搜索一些文章,但没有找到如何去做。请推荐一些完全解析 .po 的 Python 包(可能是其他语言)或工具来完成如此重要的任务以保持良好的翻译。
我需要合并/更新/删除 .po 文件消息并需要一些 Python 包,它允许我完全解析 .po 文件,包括:消息、复数、位置、上下文和注释。
我想做一个简单的工具来检查文件之间的差异。我也可以使用一些已经完成的 GUI,但不确定是否有这样的工具会添加新的翻译或删除未使用的翻译。
我正在搜索一些文章,但没有找到如何去做。请推荐一些完全解析 .po 的 Python 包(可能是其他语言)或工具来完成如此重要的任务以保持良好的翻译。
您不需要花哨的工具来读取.po
文件;它们是纯文本文件,基本上包含消息/翻译对:
#: buttons.c:425
msgid "Extra"
msgstr "Thêm"
#: buttons.c:433
msgid "Help"
msgstr "Trợ giúp"
对于比较它们的简单工具,我建议使用diff -u
.
有一个带有.mo
扩展名的二进制格式。您可以使用msgunfmt
gettext-tools 包中的程序将它们转换回纯文本。
从文件中提取 id/translation 对.po
并不困难:
In [1]: po = '''#: buttons.c:425
...: msgid "Extra"
...: msgstr "Thêm"
...:
...: #: buttons.c:433
...: msgid "Help"
...: msgstr "Trợ giúp"
...:
...: '''
In [2]: import re
In [3]: re.findall('^msgid \"(.*)\"', po, re.MULTILINE)
Out[3]: ['Extra', 'Help']
In [4]: re.findall('^msgstr \"(.*)\"', po, re.MULTILINE)
Out[4]: ['Th\xc3\xaam', 'Tr\xe1\xbb\xa3 gi\xc3\xbap']
In [5]: zip(re.findall('^msgid \"(.*)\"[^\"]*', po, re.MULTILINE), re.findall('^msgstr \"(.*)\"[^\"]*', po, re.MULTILINE))
Out[5]: [('Extra', 'Th\xc3\xaam'), ('Help', 'Tr\xe1\xbb\xa3 gi\xc3\xbap')]
我正在使用^
andre.MULTILINE
来防止注释掉的消息出现在这里。作为健全性检查,确保包含消息 ID 和消息字符串的列表长度相等。
编辑:你有一个关于随机排序和使用的有效观点diff
。但是您可以使用上面的代码为旧文件和新.po
文件创建 (message-id, translation) 元组列表。如果您按消息 ID 对这些列表进行排序,您可以使用它difflib.unified_diff
来打印差异。
例如:
In [1]: import re, itertools, difflib
#I've used cpaste to input two pieces of a .po file, the latter with some changes
In [4]: orig_po
Out[4]: '#: mixedgauge.c:64\nmsgid "Passed"\nmsgstr "\xc4\x90\xe1\xbb\x97"\n\n#: mixedgauge.c:67\nmsgid "Completed"\nmsgstr "Ho\xc3\xa0n to\xc3\xa0n"\n\n#: mixedgauge.c:70\nmsgid "Checked"\nmsgstr "\xc4\x90\xc3\xa3 ki\xe1\xbb\x83m tra"\n\n#: mixedgauge.c:73\nmsgid "Done"\nmsgstr "Ho\xc3\xa0n t\xe1\xba\xa5t"\n\n#: mixedgauge.c:76\nmsgid "Skipped"\nmsgstr "B\xe1\xbb\x8b b\xe1\xbb\x8f qua"\n\n#: mixedgauge.c:79\nmsgid "In Progress"\nmsgstr "\xc4\x90ang ch\xe1\xba\xa1y"\n\n#: mixedgauge.c:85\nmsgid "N/A"\nmsgstr "Kh\xc3\xb4ng c\xc3\xb3"\n\n#: mixedgauge.c:193\nmsgid "Overall Progress"\nmsgstr "To\xc3\xa0n ti\xe1\xba\xbfn h\xc3\xa0nh"\n'
In [5]: changed_po
Out[5]: '#: mixedgauge.c:64\nmsgid "Passed"\nmsgstr "\xc4\x90\xe1\xbb\x97"\n\n#: mixedgauge.c:193\nmsgid "Overall Progres"\nmsgstr "To\xc3\xa0n ti\xe1\xba\xbfn h\xc3\xa0nh"\n\n#: mixedgauge.c:67\nmsgid "Completed"\nmsgstr "Ho\xc3\xa0na to\xc3\xa0n"\n\n#: mixedgauge.c:76\nmsgid "Skipped"\nmsgstr "B\xe1\xbb\x8b b\xe1\xbb\x8f qua"\n\n#: mixedgauge.c:79\nmsgid "In Progress"\nmsgstr "\xc4\x90ang ch\xe1\xba\xa1y"\n\n#: mixedgauge.c:85\nmsgid "N/A"\nmsgstr "Kh\xc3\xb4ng c\xc3\xb3e"\n\n#: mixedgauge.c:70\nmsgid "Checked"\nmsgstr "\xc4\x90\xc3\xa3 ki\xe1\xbb\x83m tra"\n\n#: mixedgauge.c:73\nmsgid "Done"\nmsgstr "Ho\xc3\xa0n t\xe1\xba\xa5t"\n'
# Making a list of tuples
In [6]: orig_list = zip(re.findall('^(msgid \".*\")', orig_po, re.MULTILINE), re.findall('^(msgstr \".*\")', orig_po, re.MULTILINE))
In [7]: changed_list = zip(re.findall('^(msgid \".*\")', changed_po, re.MULTILINE), re.findall('^(msgstr \".*\")', changed_po, re.MULTILINE))
# Sort them by the message-id
In [8]: orig_list.sort(key=lambda t: t[0])
In [9]: changed_list.sort(key=lambda t: t[0])
# Now flatten the list
In [10]: orig_string_list = [i for i in itertools.chain(*orig_list)]
In [11]: changed_string_list = [i for i in itertools.chain(*changed_list)]
In [12]: orig_list[0:3]
Out[12]: [('msgid "Checked"', 'msgstr "\xc4\x90\xc3\xa3 ki\xe1\xbb\x83m tra"'), ('msgid "Completed"', 'msgstr "Ho\xc3\xa0n to\xc3\xa0n"'), ('msgid "Done"', 'msgstr "Ho\xc3\xa0n t\xe1\xba\xa5t"')]
In [13]: orig_string_list[0:6]
Out[13]: ['msgid "Checked"', 'msgstr "\xc4\x90\xc3\xa3 ki\xe1\xbb\x83m tra"', 'msgid "Completed"', 'msgstr "Ho\xc3\xa0n to\xc3\xa0n"', 'msgid "Done"', 'msgstr "Ho\xc3\xa0n t\xe1\xba\xa5t"']
# print the diff
In [14]: for l in difflib.unified_diff(orig_string_list, changed_string_list, fromfile='original', tofile='changed'):
....: print l
....:
--- original
+++ changed
@@ -1,14 +1,14 @@
msgid "Checked"
msgstr "Đã kiểm tra"
msgid "Completed"
-msgstr "Hoàn toàn"
+msgstr "Hoàna toàn"
msgid "Done"
msgstr "Hoàn tất"
msgid "In Progress"
msgstr "Đang chạy"
msgid "N/A"
-msgstr "Không có"
-msgid "Overall Progress"
+msgstr "Không cóe"
+msgid "Overall Progres"
msgstr "Toàn tiến hành"
msgid "Passed"
msgstr "Đỗ"
试试babel模块。它包括一个.po
解析器babel.messages.catalog
和babel.messages.pofile
其他东西。