К сожалению, я просто хотел извлечь строки из файла .rc, чтобы я мог их переводить, но все, что связано с файлами .rc, у меня работает.
Может, Программный локализатор RC-WinTrans? Отказ от ответственности: я не связан с ними, но в компании, в которой я работаю, люди используют старую версию для целей перевода.





Может это поможет? (http://social.msdn.microsoft.com/forums/en-US/regexp/thread/5e87fce9-ec73-42eb-b2eb-c821e95e0d31/)
Они используют следующее регулярное выражение для поиска строковой таблицы в источнике rc:
(? <= \ bSTRINGTABLE \ s + BEGIN \ s +). *? (? = \ s + END \ b)
Изменить - и вы можете прочитать пары ключевых значений с помощью следующего оператора с опцией MultiLine:
@ "\ s + (. *?) \ s +" "(. *)" "";
Это похоже на задание для сценария САС.
Запустив эту командную строку: sed.exe -n -f sed.txt test.rc
Следующий сценарий САС извлечет все строки в кавычках из входного файла 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/\(.*\)\(\".*\"\)\(.*\)// p
}
Хотя rc-файлы кажутся очевидной отправной точкой для перевода, это не так. Задача разработчиков - убедиться, что приложение переводимо. Это не для управления переводами. Начать перевод с exe, хотя и несколько нелогично, но лучше. Подробнее об этом здесь: http://www.apptranslator.com/misconceptions.html
ResxCrunch иногда скоро выйдет. Он будет редактировать несколько файлов ресурсов на нескольких языках в одной таблице.
Я бы подумал об использовании 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;
}
В случае rc лучше использовать расширенный парсер, например http://www.soft-gems.net/index.php/java/windows-resource-file-parser-and-converter
У меня нет файлов .rc. Не могли бы вы дать мне образец, чтобы я мог создать для него регулярное выражение?