Rub*_*ben 9 php regex parsing gettext poedit
我用德语中的所有文本启动了我的PHP应用程序,然后使用gettext提取所有字符串并将它们翻译成英语.
所以,现在我有一个.po文件,其中包含德语中的所有msgids和英语中的msgstrs.我想切换它们,以便我的源代码包含英文为msgids,原因有两个:
我可以手动执行此操作,这是一种任务,我预计它将花费更多时间为它编写一个自动例程(因为我对shell脚本非常糟糕)而不是手动执行.但我也期望鄙视手动计算机劳动的每一分钟(感觉就像矛盾,对吧?)就像我一直这样.
有人曾经这样做过吗?我认为这将是一个常见的问题,但找不到任何东西.非常感谢.
示例问题:
<title><?=_('Routinen')?></title>
#: /users/ruben/sites/v/routinen.php:43
msgid "Routinen"
msgstr "Routines"
Run Code Online (Sandbox Code Playgroud)
我以为我会把问题缩小..po文件中的开关当然没有问题,就像它一样简单
preg_replace('/msgid "(.+)"\nmsgstr "(.+)"/', '/msgid "$2"\nmsgstr "$1"/', $str);
Run Code Online (Sandbox Code Playgroud)
对我来说问题是在解析.po文件时搜索我的项目文件夹文件_('$msgid')
并替换的例程_('msgstr')
(在所有.po文件包含包含所有文件路径的注释之后,这可能不是最优雅的方式) msgstr发生).
之后鬼混与akirk的回答一点,我遇到了一些更多的问题.
_('xxx')
和_("xxx")
调用,所以我必须小心(un)转义.
msgid = ""
"line 1\n"
"line 2\n"
msgstr = ""
"line 1\n"
"line 2\n"
我今晚必须停止工作.似乎仍然使用解析器而不是RegExps不会有点矫枉过正.
我建立在akirk的答案之上,并希望在这里保留我想出的答案,以防有人遇到同样的问题.这不是递归的,但当然可以很容易地改变.随意改进评论,我将观看和编辑这篇文章.
$po = file_get_contents("locale/en_GB/LC_MESSAGES/messages.po");
$translations = array(); // german => english
$rawmsgids = array(); // find later
$msgidhits = array(); // record success
$msgstrs = array(); // find later
preg_match_all('/msgid "(.+)"\nmsgstr "(.+)"/', $po, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$german = str_replace('\"','"',$match[1]); // unescape double quotes (could misfire if you escaped double quotes in PHP _("<a href=\"bla\">bla</a>") but in my case that was one case versus many)
$english = str_replace('\"','"',$match[2]);
$en_sq_e = str_replace("'","\'",$english); // escape single quotes
$translations['_(\''. $german . '\''] = '_(\'' . $en_sq_e . '\'';
$rawmsgids['_(\''. $german . '\''] = $match[1]; // find raw msgid with searchstr as key
$translations['_("'. $match[1] . '"'] = '_("' . $match[2] . '"';
$rawmsgids['_("'. $match[1] . '"'] = $match[1];
$translations['__(\''. $german . '\''] = '__(\'' . $en_sq_e . '\'';
$rawmsgids['__(\''. $german . '\''] = $match[1];
$translations['__("'. $match[1] . '"'] = '__("' . $match[2] . '"';
$rawmsgids['__("'. $match[1] . '"'] = $match[1];
$msgstrs[$match[1]] = $match[2]; // msgid => msgstr
}
foreach (glob("*.php") as $file) {
$code = file_get_contents($file);
$filehits = 0; // how many replacements per file
foreach($translations AS $msgid => $msgstr) {
$hits = 0;
$code = str_replace($msgid,$msgstr,$code,$hits);
$filehits += $hits;
if($hits!=0) $msgidhits[$rawmsgids[$msgid]] = 1; // this serves to record if the msgid was found in at least one incarnation
elseif(!isset($msgidhits[$rawmsgids[$msgid]])) $msgidhits[$rawmsgids[$msgid]] = 0;
}
// file_put_contents($file, $code); // be careful to test this first before doing the actual replace (and do use a version control system!)
echo "$file : $filehits <br>";
echo $code;
}
/* debug */
$found = array_keys($msgidhits, 1, true);
foreach($found AS $mid) echo $mid . " => " . $msgstrs[$mid] . "\n\n";
echo "Not Found: <br>";
$notfound = array_keys($msgidhits, 0, true);
foreach($notfound AS $mid) echo $mid . " => " . $msgstrs[$mid] . "\n\n";
/*
following steps are still needed:
* convert plurals (ngettext)
* convert multi-line msgids and msgstrs (format mentioned in question)
* resolve uniqueness conflict (msgids are unique, msgstrs are not), so you may have duplicate msgids (poedit finds these)
*/
Run Code Online (Sandbox Code Playgroud)
请参阅http://code.activestate.com/recipes/475109-regular-expression-for-python-string-literals/,了解一个基于 python 的正则表达式,用于查找字符串文字,并考虑转义。虽然它是 python,但这对于多行字符串和其他极端情况可能非常好。
请参阅http://docs.translatehouse.org/projects/translate-toolkit/en/latest/commands/poswap.html,了解 .po 文件的现成的、开箱即用的基本语言交换器。
例如,以下命令行会将基于德语的西班牙语翻译转换为基于英语的西班牙语翻译。您只需在开始转换之前确保新的基本语言(英语)已 100% 翻译:
poswap -i de-en.po -t de-es.po -o en-es.po
Run Code Online (Sandbox Code Playgroud)
最后要将英语 po 文件交换为德语 po 文件,请使用 swappo: http: //manpages.ubuntu.com/manpages/hardy/man1/swappo.1.html
交换文件后,可能需要对结果文件进行一些手动修改。例如,标题可能会被破坏,并且可能会出现一些重复的文本。
归档时间: |
|
查看次数: |
2853 次 |
最近记录: |