2015-01-16 2 views
0

Несколько дней назад я наткнулся на jquery.i18n из фонда wikimedia, который позволяет переводить строки, такие как Welcome, $1 и Found $1 {{PLURAL:$1|result|results}}.Анализ языка шаблонов в php

Я хотел бы воссоздать эту функциональность в PHP только для образовательных целей.

Мне удалось создать парсер, который анализирует строки, такие как Welcome, $1, но теперь я ищу, чтобы воссоздать вторую функциональность Found $1 {{METHOD:$1|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); 
} 

ответ

1

Это, кажется, работает хорошо:

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 $1 {{PLURAL:$1|mouse|mice}} and $2 {{PLURAL:$2|apple|apples}}\n"; 

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

Идея заключается в том, чтобы заменить все (доллары и фигурные скобки) в один раз и предпринять соответствующие действия в функции замены. Вы можете добавить больше «методов», например «множественное число», указав дополнительные функции handle_xxx.

+0

Отлично, это именно то, что я имел в виду. Спасибо! – frietkot

Смежные вопросы