正在 php 中解析模板语言

Parsing template language in php

几天前,我从维基媒体基金会了解到 jquery.i18n,它可以翻译 Welcome, Found {{PLURAL:|result|results}}.

等字符串

出于教育目的,我想在 PHP 中重新创建该功能。

我能够创建一个解析器来解析像 Welcome, 这样的字符串,但现在我想重新创建第二个功能 Found {{METHOD:|parameters|...}} 但我不知道如何创建一些功能来做到这一点.

谁能把我推向正确的方向?我已经看过 jquery.i18n 库的源代码,我不打算实现另一个现有的翻译库,只是自己创建一个。

这是我得到的简单参数解析函数:

public function parse($message, $replacements)
{
    if (strrpos($message, '{{') === false) {
        return $this->simpleParse($message, $replacements);
    }
}

protected function simpleParse($message, $replacements)
{
    return preg_replace_callback('/$(\d+)/', function ($match) use ($replacements) {
        $key = $match[1] - 1;
        if (isset($replacements[$key])) {
            return $replacements[$key];
        }

        return $match[0];
    }, $message);
}

这似乎工作得很好:

function parse($msg, $args) {
    return preg_replace_callback('~{{(\w+):(.+?)}}|$(\d+)~', function($m) use($args) {
        if(strlen($m[1]))
            return parse_func(
                strtolower($m[1]),
                explode('|', $m[2]),
                $args);
        return $args[$m[3] - 1];
    }, $msg);
}

function parse_func($name, $params, $args) {
    foreach($params as &$p) {
        if(preg_match('~^$(\d+)$~', $p, $m))
            $p = $args[$m[1] - 1];
    }
    return call_user_func_array("handle_$name", $params);
}

function handle_plural($value, $sing, $plu) {
    return intval($value) > 1 ? $plu : $sing;
}

// works!

$msg = "Found  {{PLURAL:|mouse|mice}} and  {{PLURAL:|apple|apples}}\n";

print parse($msg, [1, 5]);
print parse($msg, [6, 1]);

想法是立即替换所有内容(美元和大括号)并在替换函数中采取适当的操作。您可以通过定义额外的 handle_xxx 函数来添加更多 'methods',例如 "plural"。