2008-09-10 29 views
1

Ulrichly我只是想从.rc文件中提取字符串,所以我可以翻译它们,但任何与.rc文件一起使用的东西都适用于我。解析资源(.rc)文件的正则表达式

+0

我没有任何的.rc文件,可以:通过gettext和每个对话使用这样的功能转换在启动的字符串PO文件你给我一个样本,以便我可以为它创建一个正则表达式? – Teifion 2008-09-10 08:37:01

回答

0

这听起来像是一个SED脚本的工作。

运行以下命令行:sed.exe -n -f sed.txt test.rc

以下SED脚本将提取所有引用的字符串从输入test.rc文件:

# Run Script Using This Command Line 
# 
# sed.exe -n -f sed.txt test.rc 
# 

# Check for lines that contain strings 
/\".*\"/ { 
    # print the string part of the line only 
    s/\(.*\)\(\".*\"\)\(.*\)/\2/ p 
} 
1

对于真实世界的项目,你会想,不仅提取它们也将它们放回,并跟踪更新。除了最微不足道的应用程序之外,这对于任何事情都是难以管理的。看看像appTranslator(www.apptranslator.com)这样的专业软件。不是免费的,但一些正则表达式解析不会削减它 - 我知道,我已经尝试了很多。

1

尽管rc文件似乎是一个明显的翻译起点,但事实并非如此。 开发人员的工作是确保应用程序是可翻译的。这不是管理翻译。从exe开始翻译,虽然有点反直觉,但这是一个更好的主意。 阅读更多关于它的地方:http://www.apptranslator.com/misconceptions.html

-2

ResxCrunch有时会很快出来。 它将在一张表中编辑多种语言的多个资源文件。

1

我会考虑的gettext.PO files使用,如果你的程序符合GNU许可证

1)我建议使用状态机算法的.rc文件中提取。

void ProcessLine(const char * str) 
{ 
    if (strstr(str, " DIALOG")) 
     state = Scan; 
    else if (strstr(str, " MENU")) 
     state = Scan; 
    else if (strstr(str, " STRINGTABLE")) 
     state = Scan; 
    else if (strstr(str, "END")) 
     state = DontScan; 

    if (state == Scan) 
    { 
     const char * cur = sLine; 
     string hdr = ...// for example "# file.rc:453" 
     string msgid; 
     string msgid = ""; 
     while (ExtractString(sLine, cur, msgid)) 
     { 
     if (msgid.empty()) 
      continue; 
     if (IsPredefined(msgid)) 
      continue; 
     if (msgid.find("IDB_") == 0 || msgid.find("IDC_") == 0) 
      continue; 
     WritePoString(hdr, msgid, msgstr); 
     } 
    } 
} 

2)提取里面ExtractString(串),你应该考虑字符“被表示为‘’,并且也有字符像\ t \ n \ r。所以状态机也在这里一个不错的选择。

以下字符串:

LTEXT   "Mother has washed ""Sony"", then \taquarium\\shelves\r\nand probably floors",IDC_TEXT1,24,14,224,19 

代表在对话这样的标签:

Mother has washed "Sony", then aquarium\shelves 
and probably floors 

3)然后在程序启动时,您应该加载。

int TranslateDialog(CWnd& wnd) 
{ 
    int i = 0; 
    CWnd *pChild; 
    CString text; 

    //Translate Title 
wnd.GetWindowText(text); 
LPCTSTR translation = Translate(text); 
    window.SetWindowText(translation); 

    //Translate child windows 
    pChild=wnd.GetWindow(GW_CHILD); 
    while(pChild) 
    { 
     i++; 
    Child->GetWindowText(Text);//including NULL 
     translation = Translate(Text); 
     pChild->SetWindowText(translation); 
     pChild = pChild->GetWindow(GW_HWNDNEXT); 
    } 
    return i; 
}