регулярное выражение для анализа файлов ресурсов (.rc) - PullRequest
2 голосов
/ 10 сентября 2008

Я просто хотел извлечь строки из файла .rc, чтобы перевести их, но все, что связано с файлами .rc, работает для меня.

Ответы [ 6 ]

2 голосов
/ 29 ноября 2012

Я бы рассмотрел использование gettext и .PO файлов , если ваша программа соответствует лицензии 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 () вы должны учитывать, что char "представлен как" ", и есть также символы типа \ 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) Затем при запуске программы вы должны загрузить .po файл через gettext и для каждого диалога перевести свою строку при запуске, используя такую ​​функцию:

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;
}
1 голос
/ 21 сентября 2008

Хотя rc файлы кажутся очевидной отправной точкой для перевода, это не так. Задача разработчиков - убедиться, что приложение является переводимым. Это не для управления переводами. Начинать переводы с exe, хотя и несколько нелогично, - это лучшая идея Подробнее об этом здесь: http://www.apptranslator.com/misconceptions.html

1 голос
/ 10 сентября 2008

Может быть, это поможет? (http://social.msdn.microsoft.com/forums/en-US/regexp/thread/5e87fce9-ec73-42eb-b2eb-c821e95e0d31/)

Они используют следующее регулярное выражение для поиска строки в источнике rc:

(? <= \ BSTRINGTABLE \ S + НАЧАТЬ \ S +). * (? = \ S + END \ б) </p>

Редактировать - и вы можете прочитать пары значений ключа с помощью следующего оператора с опцией MultiLine:

@ "\ s + (. *) \ S +" "" "" (. *);

0 голосов
/ 16 ноября 2014

В случае rc лучше использовать расширенный парсер, например http://www.soft -gems.net / index.php / java / windows-resource-file-parser-and-converter

0 голосов
/ 20 марта 2009

ResxCrunch скоро выйдет. Он будет редактировать несколько файлов ресурсов на нескольких языках в одной таблице.

0 голосов
/ 19 сентября 2008

Это звучит как работа для сценария 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...