改进 PHP 的 sprintf

发布于 2024-12-27 16:15:54 字数 554 浏览 2 评论 0原文

有谁知道sprintfPHP中的更好实现吗?我一直在寻找类似于Python中的字符串格式的东西:

print "Hello %(name)s. Your %(name)s has just been created!" % { 'name' : 'world' }
# prints::: Hello world. Your world has just been created!

这非常方便,可以避免不必要地重复相同的变量,例如:

sprintf("Hello %s. Your %s has just been created!", 'world', 'world');
# prints::: Hello world. Your world has just been created!

我想自己构建这个相当容易,但不想重新发明轮子,如果你明白我的意思......但我无法在任何地方找到(可能是错误的搜索关键字)任何痕迹。

如果有人可以提供帮助,我很感激。

干杯,

Does anyone know a better implementation of sprintf in PHP? I was looking for something like the string formatting we have in python:

print "Hello %(name)s. Your %(name)s has just been created!" % { 'name' : 'world' }
# prints::: Hello world. Your world has just been created!

This is pretty handy to avoid repeating the same variables without need, such as:

sprintf("Hello %s. Your %s has just been created!", 'world', 'world');
# prints::: Hello world. Your world has just been created!

I guess is fairly easy to build this on my own, but don't wanna reinvent the wheel, if you know what I mean... but I could not find (maybe wrong search keywords) any trace of this anywhere.

If anyone can help, I appreciate.

Cheers,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

梦里人 2025-01-03 16:15:55

以下代码是从 的帖子中盗取的TalkPHP 上的 Salathe

$szAdjective = 'fluffy';
$szNoun = 'cat';

printf('Yesterday, I saw a %s. '.
       'It was a %s %s! I have '.
       'never seen a %s quite so %s.',
       $szNoun,
       $szAdjective,
       $szNoun,
       $szNoun,
       $szAdjective);

printf('Yesterday, I saw a %1$s. '.
       'It was a %2$s %1$s! I have '.
       'never seen a %1$s quite so %2$s.',
       $szNoun,
       $szAdjective);

上面两个表达式是等价的,都会输出

“昨天,我看到一只猫。那是一只毛茸茸的猫!我从来没有见过这么毛茸茸的猫。”

The following code was stolen from a post by Salathe on TalkPHP.

$szAdjective = 'fluffy';
$szNoun = 'cat';

printf('Yesterday, I saw a %s. '.
       'It was a %s %s! I have '.
       'never seen a %s quite so %s.',
       $szNoun,
       $szAdjective,
       $szNoun,
       $szNoun,
       $szAdjective);

printf('Yesterday, I saw a %1$s. '.
       'It was a %2$s %1$s! I have '.
       'never seen a %1$s quite so %2$s.',
       $szNoun,
       $szAdjective);

The above two expressions are equivalent and will both output

"Yesterday, I saw a cat. It was a fluffy cat! I have never seen a cat quite so fluffy."

弥繁 2025-01-03 16:15:55

我在另一篇文章中回答了这个问题: 带有命名参数的 vsprintf 或 sprintf,或者 PHP 中的简单模板解析

但这具有相同的格式你正在寻找!

恕我直言,这确实是最好的方式。没有神秘字符,只需使用键名即可!

取自 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

I answered this very question in another post: vsprintf or sprintf with named arguments, or simple template parsing in PHP

But this has the same format youre looking for!

This is really the best way to go imho. No cryptic characters, just use the key names!

As taken from the php site:
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
拥醉 2025-01-03 16:15:55

我编写了一个小组件,允许您在 php 字符串中进行名称替换。它称为 StringTemplate
有了它,您可以通过如下代码获得您想要的内容:

$engine = new StringTemplate\Engine;

$engine->render(
   '"Hello {name}. Your {name} has just been created!"',
   [
      'name' => 'world',
   ]
);
//Prints "Hello world. Your world has just been created!"

也允许多维数组值。希望能有所帮助。

I've written a small component that allow you to make name substitutions in php strings. It's called StringTemplate.
With it you can get what you want with a code like this:

$engine = new StringTemplate\Engine;

$engine->render(
   '"Hello {name}. Your {name} has just been created!"',
   [
      'name' => 'world',
   ]
);
//Prints "Hello world. Your world has just been created!"

Multidimensional array value are allowed too. Hope that can help.

蓦然回首 2025-01-03 16:15:54

您可以使用位置(但不是命名)参数来执行此操作,例如

printf('Hello %1$s. Your %1$s has just been created!', 'world'); 

此处请注意:您必须使用 引号,否则美元符号将导致 PHP 尝试替换 $ s 带有此变量的值(该变量不存在)。

如果您想要命名参数,那么您将必须使用正则表达式来完成此操作;例如,请参阅如何用实际值替换占位符?

You can use positional (but not named) arguments to do this, for example

printf('Hello %1$s. Your %1$s has just been created!', 'world'); 

A word of caution here: you must use single quotes, otherwise the dollar signs will cause PHP to try to substitute $s with the value of this variable (which does not exist).

If you want named arguments then you will have to do this with a regular expression; for example, see How to replace placeholders with actual values?.

§对你不离不弃 2025-01-03 16:15:54

可以使用 PHP 的 sprintf 重复相同的占位符(尽管它可能看起来不太好):

$str = sprintf('%1$s %1$s', 'yay');
// str: 'yay yay'

您可以在 n$ 之后使用 n$ >% 在占位符中,其中 n 是参数位置(因此 %1$s 指的是第一个参数(作为字符串),%2$s 指第二个,依此类推)。正如您在上面看到的,当您使用位置绑定的占位符时,您可以在调用 sprintf 时在字符串中重复它们,而无需重复参数。

You can repeat the same placeholder with PHP's sprintf (though it might not look as nice):

$str = sprintf('%1$s %1$s', 'yay');
// str: 'yay yay'

You can use n$ right after the % in a placeholder, where n is the argument position (so %1$s refers to the first argument (as a string), %2$s refers to the second, etc.). As you can see above, when you use placeholders that are positionally-bound, you can repeat them within the string without duplicating arguments when you call sprintf.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文