代码之家  ›  专栏  ›  技术社区  ›  djeidot

用于分析资源(.rc)文件的正则表达式

  •  2
  • djeidot  · 技术社区  · 16 年前

    当然,我只是想从.rc文件中提取字符串,这样我就可以翻译它们,但是任何与.rc文件一起使用的东西都对我有效。

    6 回复  |  直到 16 年前
        1
  •  2
  •   blackbada_cpp    12 年前

    我会考虑使用 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)然后在程序启动时,您应该通过gettext加载.po文件,对于每个对话框,在启动时使用如下函数转换其字符串:

    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;
    }
    
        2
  •  1
  •   Thomas    16 年前

    也许这有帮助?( http://social.msdn.microsoft.com/forums/en-US/regexp/thread/5e87fce9-ec73-42eb-b2eb-c821e95e0d31/ )

    他们使用以下regex在rc源代码中查找stringtable:

    (?<=\bSTRINGTABLE\s+BEGIN\s+。*?(?=\s+结束\b)

    编辑-您可以使用多行选项读取带有以下语句的键值对:

    @“\s+(.*?)\s+“”(.*“”);

        3
  •  1
  •   Serge Wautier    16 年前

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

        4
  •  0
  •   jussij    16 年前

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

    通过运行此命令行: sed.exe-n-f sed.txt测试.rc

    以下 塞德 脚本将提取所有 带引号的字符串 从输入 测试.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
    }
    
        5
  •  0
  •   Maxim Kapitonov    10 年前
        6
  •  -2
  •   Germstorm Pierre-Alain Vigeant    15 年前

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