改进的PHP sprintf

4 投票
5 回答
1354 浏览
提问于 2025-04-17 10:34

有没有人知道在 PHP 中有没有更好的 sprintf 实现?我在找类似于我们在 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!

我想自己写一个这个功能应该不难,但我不想重复造轮子,你懂的……不过我找了半天(可能是搜索关键词不对),也没找到任何相关的信息。

如果有人能帮忙,我会很感激。

谢谢!

5 个回答

3

以下代码是从Salathe在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);

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

"昨天,我看到了一只猫。它是一只毛茸茸的猫!我从来没有见过这么毛茸茸的猫。"

5

你可以用PHP的 sprintf 函数重复使用同一个占位符(虽然看起来可能不太好)。

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

在占位符中的 % 后面,你可以使用 n$,其中 n 是参数的位置(比如 %1$s 表示第一个参数(作为字符串),%2$s 表示第二个,以此类推)。正如你在上面看到的,当你使用位置绑定的占位符时,你可以在字符串中重复使用它们,而不需要在调用 sprintf 时重复传递参数。

8

你可以使用位置参数(但不能使用命名参数)来做到这一点,比如说:

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

这里有个小提醒:你必须使用单引号,否则美元符号会让PHP试图用这个变量的值来替换$s(但这个变量并不存在)。

如果你想使用命名参数,那就得用正则表达式来实现;例如,可以参考这个链接:如何用实际值替换占位符?

撰写回答