vsprintf или sprintf с именованными аргументами или простой анализ шаблонов в PHP

Я ищу способ использования именованных аргументов для sprintf или printf .

Пример:

 sprintf( 'Last time logged in was %hours hours, %minutes minutes, %seconds seconds ago' ,$hours,$minutes, $seconds ); 

или через vsprintf и ассоциативный массив.

Я нашел некоторые примеры кодирования здесь

 function sprintfn ($format, array $args = array()) 

http://php.net/manual/de/function.sprintf.php

и здесь

 function vnsprintf( $format, array $data) 

http://php.net/manual/de/function.vsprintf.php

где люди пишут собственные решения.

Но мой вопрос в том, может ли быть стандартное решение PHP для достижения этого или есть другой способ, возможно, с помощью простого шаблона PHP, предоставленного PEAR, что я могу достичь этого, придерживаясь стандартного PHP?

Спасибо за любую помощь.

Related of "vsprintf или sprintf с именованными аргументами или простой анализ шаблонов в PHP"

Насколько я знаю, printf / sprintf не принимает массивы-члены.

Однако можно сделать printf('%1$d %1$d', 1);

Лучше чем ничего 😉

Я написал небольшой компонент именно для этой потребности. Это называется StringTemplate . С его помощью вы можете получить то, что хотите, с таким кодом:

 $engine = new StringTemplate\Engine; $engine->render( 'Last time logged in was {hours} hours, {minutes} minutes, {seconds} seconds ago', [ 'hours' => '08', 'minutes' => 23, 'seconds' => 12, ] ); //Prints "Last time logged in was 08 hours, 23 minutes, 12 seconds ago" 

Надеюсь, что это поможет.

Это от php.net

 function vnsprintf( $format, array $data) { preg_match_all( '/ (?<!%) % ( (?: [[:alpha:]_-][[:alnum:]_-]* | ([-+])? [0-9]+ (?(2) (?:\.[0-9]+)? | \.[0-9]+ ) ) ) \$ [-+]? \'? .? -? [0-9]* (\.[0-9]+)? \w/x', $format, $match, PREG_SET_ORDER | PREG_OFFSET_CAPTURE); $offset = 0; $keys = array_keys($data); foreach( $match as &$value ) { if ( ( $key = array_search( $value[1][0], $keys, TRUE) ) !== FALSE || ( is_numeric( $value[1][0] ) && ( $key = array_search( (int)$value[1][0], $keys, TRUE) ) !== FALSE) ) { $len = strlen( $value[1][0]); $format = substr_replace( $format, 1 + $key, $offset + $value[1][1], $len); $offset -= $len - strlen( 1 + $key); } } return vsprintf( $format, $data); } 

Пример:

 $example = array( 0 => 'first', 'second' => 'second', 'third', 4.2 => 'fourth', 'fifth', -6.7 => 'sixth', 'seventh', 'eighth', '9' => 'ninth', 'tenth' => 'tenth', '-11.3' => 'eleventh', 'twelfth' ); echo vnsprintf( '%1$s %2$s %3$s %4$s %5$s %6$s %7$s %8$s %9$s %10$s %11$s %12$s<br />', $example); // acts like vsprintf echo vnsprintf( '%+0$s %second$s %+1$s %+4$s %+5$s %-6.5$s %+6$s %+7$s %+9$s %tenth$s %-11.3$s %+10$s<br />', $example); 

Пример 2:

 $examples = array( 2.8=>'positiveFloat', // key = 2 , 1st value -3=>'negativeInteger', // key = -3 , 2nd value 'my_name'=>'someString' // key = my_name , 3rd value ); echo vsprintf( "%%my_name\$s = '%my_name\$s'\n", $examples); // [unsupported] echo vnsprintf( "%%my_name\$s = '%my_name\$s'\n", $examples); // output : "someString" echo vsprintf( "%%2.5\$s = '%2.5\$s'\n", $examples); // [unsupported] echo vnsprintf( "%%2.5\$s = '%2.5\$s'\n", $examples); // output : "positiveFloat" echo vsprintf( "%%+2.5\$s = '%+2.5\$s'\n", $examples); // [unsupported] echo vnsprintf( "%%+2.5\$s = '%+2.5\$s'\n", $examples); // output : "positiveFloat" echo vsprintf( "%%-3.2\$s = '%-3.2\$s'\n", $examples); // [unsupported] echo vnsprintf( "%%-3.2\$s = '%-3.2\$s'\n", $examples); // output : "negativeInteger" echo vsprintf( "%%2\$s = '%2\$s'\n", $examples); // output : "negativeInteger" echo vnsprintf( "%%2\$s = '%2\$s'\n", $examples); // output : [= vsprintf] echo vsprintf( "%%+2\$s = '%+2\$s'\n", $examples); // [unsupported] echo vnsprintf( "%%+2\$s = '%+2\$s'\n", $examples); // output : "positiveFloat" echo vsprintf( "%%-3\$s = '%-3\$s'\n", $examples); // [unsupported] echo vnsprintf( "%%-3\$s = '%-3\$s'\n", $examples); // output : "negativeInteger" 

Я знаю, что это было разрешено слишком долго, но, может быть, мое решение достаточно простое, но полезно для кого-то другого.

С помощью этой небольшой функции вы можете имитировать простую систему шаблонов:

 function parse_html($html, $args) { foreach($args as $key => $val) $html = str_replace("#[$key]", $val, $html); return $html; } 

Используйте его так:

 $html = '<h1>Hello, #[name]</h1>'; $args = array('name' => 'John Appleseed'; echo parse_html($html,$args); 

Это приведет к выводу:

 <h1>Hello, John Appleseed</h1> 

Может быть, не для всех и для каждого случая, но это спасло меня.

Это действительно лучший способ пойти имхо. Никаких загадочных символов, просто используйте имена ключей!

Как взят с сайта php: http://www.php.net/manual/en/function.vsprintf.php

 function dsprintf() { $data = func_get_args(); // get all the arguments $string = array_shift($data); // the string is the first one if (is_array(func_get_arg(1))) { // if the second one is an array, use that $data = func_get_arg(1); } $used_keys = array(); // get the matches, and feed them to our function $string = preg_replace('/\%\((.*?)\)(.)/e', 'dsprintfMatch(\'$1\',\'$2\',\$data,$used_keys)',$string); $data = array_diff_key($data,$used_keys); // diff the data with the used_keys return vsprintf($string,$data); // yeah! } function dsprintfMatch($m1,$m2,&$data,&$used_keys) { if (isset($data[$m1])) { // if the key is there $str = $data[$m1]; $used_keys[$m1] = $m1; // dont unset it, it can be used multiple times return sprintf("%".$m2,$str); // sprintf the string, so %s, or %d works like it should } else { return "%".$m2; // else, return a regular %s, or %d or whatever is used } } $str = <<<HITHERE Hello, %(firstName)s, I know your favorite PDA is the %(pda)s. You must have bought %(amount)s HITHERE; $dataArray = array( 'pda' => 'Newton 2100', 'firstName' => 'Steve', 'amount' => '200' ); echo dsprintf($str, $dataArray); // Hello, Steve, I know your favorite PDA is the Newton 2100. You must have bought 200 

См. Выполнение drupal

https://api.drupal.org/api/drupal/includes%21bootstrap.inc/function/format_string/7

Это просто и не использует регулярное выражение

 function format_string($string, array $args = array()) { // Transform arguments before inserting them. foreach ($args as $key => $value) { switch ($key[0]) { case '@': // Escaped only. $args[$key] = check_plain($value); break; case '%': default: // Escaped and placeholder. $args[$key] = drupal_placeholder($value); break; case '!': // Pass-through. } } return strtr($string, $args); } function drupal_placeholder($text) { return '<em class="placeholder">' . check_plain($text) . '</em>'; } 

Пример:

 $unformatted = 'Hello, @name'; $formatted = format_string($unformatted, array('@name' => 'John')); 

Достаточно просто

 <?php //sprintf with place holders function printPh($string,Array $params){ $tok = strtok($string,':'); $msg = ''; while($tok !== false){ $msg .= array_key_exists($tok,$params) ? $params[$tok] : $tok; $tok = strtok(':'); } return $msg; } echo spfwph('<p>:ph1: :ph2:</p>',['ph1'=>'placerholder 1','ph2'=>'placeholder 2']);