正在 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"。
几天前,我从维基媒体基金会了解到 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"。