2

我的问题很简单,我使用 gettext 来翻译 URL,因此我只有 url 字符串的翻译版本。

我想知道是否有一种简单的方法可以从翻译的字符串中获取基本字符串?

我的想法是在每次使用我的_u($string)函数时自动将翻译后的名称添加到数据库中,并使用基本字符串为其命名。

我目前拥有的:

function _u($string)
{
    if (empty($string))
        return '';
    else
        return dgettext('Urls', $string);
}

我在想什么(伪代码):

function _u($string)
{
    if (empty($string))
        return '';

    $translation = dgettext('Urls', $string);

    MySQL REPLACE INTO ... base = $string, translation = $translation; (translation = primary key)

    return $translation;
}

function url_base($translation)
{
    $row = SELECT ... FROM ... translation = $translation;

    return $base;
}

尽管这似乎不是做到这一点的最佳方法,而且如果在生产中我删除了该REPLACE部件,那么我可能会忘记生产中的一两个我可能没有去过的链接。

编辑:我主要寻找的是 gettext 的解析部分。我不需要错过任何可能的 URL,因此如果您有其他解决方案,则需要有一个解析器(基于我正在寻找的内容)。

EDIT2:刚刚添加了另一个难度。我们必须在任何翻译中找到 URL 并将其放回“基本”翻译中,以便系统解析基本语言中的 URL。

4

1 回答 1

4

msgunfmt实际上,我能想到的最直接的方法是通过调用实用程序来解码用于翻译的 .mo 文件。

一旦你有了明文数据库,你就可以将它保存在任何其他类型的数据库中,然后就可以进行反向搜索了。

但也许更好的是,您可以创建额外的域(“ReverseUrlsIT”),将翻译后的 URL 存储为键,并将基值存储为值(假设映射是完全双向的,即!)。

此时,您可以使用dgettext从已翻译字符串中恢复基本字符串,前提是您知道已翻译字符串的语言。

更新

这是使用 gettext 的要点,如果我能找到另一个可以提供帮助的解析器/库/工具,我会随时放弃它

毕竟,gettext功能家族只不过是一个密钥库数据库系统,它具有(也许)一个比printf, 处理复数和形容词/名词反转更强大的解析器(英语中的violin virtuoso变成了virtuoso di意大利语的小提琴)。

以增加数据库复杂性(和负载)为代价,您可以构建一个密钥库,利用您方便的任何持久层(gettext毕竟是基于文件的):

TABLE LanguageDomain
{
    PRIMARY KEY ldId;
    varchar(?)  ldValue;
}
# e.g.
# 39   it_IT
# 44   en_US
# 01   us_US

TABLE Shorthand
{
    PRIMARY KEY shId;
    varchar(?)  shValue;
}

# e.g.
# 1    CAMERA
# 2    BED

TABLE Translation
{
    KEY t_ldId,
        t_shId;
    varchar(?)  t_Value;   // Or one value for singular form, one for plural...
}

# e.g.
# 44    1    Camera
# 39    1    Macchina fotografica
# 01    1    Camera
# 44    1    Bed
# 39    1    Letto
# 01    1    Bed
# 01  137    Behavior
# 44  137    Behaviour     # "American and English have many things in common..."
# 01  979    Cookie
# 44  979    Biscuit       " "...except of course the language" (O. Wilde)

function translate($string, $arguments = array())
{
    GLOBAL $languageDomain;
    // First recover main string
    SELECT t_Value FROM Translation AS t
        LEFT JOIN LanguageDomain AS l ON (t.ldId = l.ldId AND l.ldValue = :LangDom)
        LEFT JOIN Shorthand      AS s ON (t.t_shId = s.shId AND s.shValue=:String);
    // 
    if (empty($arguments))
        return $Result;
    // Now run replacement of arguments - if any
    $replacements = array();
    foreach($arguments as $n => $argument)
        $replacements["\${$n}"] = translate($argument);
    // Now replace '$1' with translation of first argument, etc.
    return str_replace(array_keys($replacements), array_values($replacements), $Result);
}

这将允许您轻松地再添加一个languageDomain,甚至可以运行诸如“哪些英语术语尚未翻译成德语?”之类的查询。(即,将具有英语域 IdLEFT JOINTranslation表的子集与具有德语域 Id 的子集结合起来时具有 NULL 值)。

该系统可与 POfile 互操作,如果您需要将翻译外包给使用行业标准工具的人,这一点很重要。但是您可以轻松地将查询直接输出为 TMX 格式,从而消除重复(在某些情况下,这可能会真正降低您的翻译成本 - 一些服务对“奇怪”格式(如 Excel)的输入多收费,或者会因“重复数据删除”而多收费或将对每份副本收取费用,就好像它是原件一样)。

<?xml version="1.0" ?>
<tmx version="1.4">
        <header
                creationtool="MySQLgetText"
                creationtoolversion="0.1-20120827"
                datatype="PlainText"
                segtype="sentence"
                adminlang="en-us"
                srclang="EN"
                o-tmf="ABCTransMem">
        </header>
        <body>
                <tu tuid="BED" datatype="plaintext">
                        <tuv xml:lang="en">
                                <seg>bed</seg>
                        </tuv>
                        <tuv xml:lang="it">
                                <seg>letto</seg>
                        </tuv>
                </tu>
                <tu tuid="CAMERA" datatype="plaintext">
                        <tuv xml:lang="en">
                                <seg>camera</seg>
                        </tuv>
                        <tuv xml:lang="it">
                                <seg>macchina fotografica</seg>
                        </tuv>
                </tu>
        </body>
</tmx>
于 2012-08-26T22:24:48.303 回答