Friday, September 05, 2008

解析Po文件

坐在偶右边的同事,需要把翻译文件一个一个拷贝到 excel表格,很是费力,问我有什么办法?看了看,第一感觉就是写 shell 提取数据啊,发现自己对 shell 并不精通,C++还可以,只好用牛刀杀鸡了。
zh_cn.po 的格式大概如下:

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR , YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: 0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-08-28 10:16+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: src/interface.c:53 src/interface.c:197
msgid "Settings"
msgstr "设置"

#: src/interface.c:63
msgid "OK"
msgstr "确定"
#~ msgid "Please insert SIM Card!"
#~ msgstr "请插入SIM卡!"

#~ msgid "Couldn't find pixmap file: %s"
#~ msgstr "不能找到图标文件:%s"

extrac_po.cpp:


/**
Filename: extract_po.cpp
Description: extract po data for zhanglingling
Version: 1.0
Created: 09/04/2008 09:57:17 PM

Author: Liqing Huang (deli), hlqing@gmail.com
Company: Broncho
*/

#include <vector>
#include <string>
#include <fstream>
#include <iostream>
#include <stdexcept>

using namespace std;

int main(int argc, char *argv[])
{
if (argc != 2) {
cerr << "Usage: extract_po po_file" << endl;
return -1;
}

string file_name = argv[1];
ifstream infile(file_name.c_str(), ios::in);

if (! infile) {
cerr << "oops: unable to open PO file"
<< file_name << endl;
return -2;
}

string tmp;
string tmp2;
vector vecs_en;
vector vecs_cn;

try {
while (getline(infile, tmp, '\n')) {
if (tmp[0] == '\0'
| tmp[0] == '\"'
| (tmp[0] == '#' && tmp[1] == ':')
| (tmp[0] == '#' && tmp[1] == ',')
| (tmp[0] == '#' && tmp[1] == ' '))
continue;

if (tmp.find("msgid", 0) != string::npos) {
tmp2 = tmp.substr(tmp.find('\"'));
vecs_en.push_back(tmp2.substr(
tmp2.find_first_of('\"') + 1,
tmp2.find_last_of('\"') - 1));
} else if (tmp.find("msgstr", 0) != string::npos) {
tmp2 = tmp.substr(tmp.find('\"'));
vecs_cn.push_back(tmp2.substr(
tmp2.find_first_of('\"') + 1,
tmp2.find_last_of('\"') - 1));
}
}
} catch (exception& e) {
cout << e.what() << endl;
}

typedef vector::const_iterator iter;
for (iter i = vecs_en.begin(); i != vecs_en.end(); ++i) {
cout << *i << endl;
}

for (iter i = vecs_cn.begin(); i != vecs_cn.end(); ++i) {
cout << *i << endl;
}

return 0;
}

No comments: