Menu

PHP sprintf():格式化字符串、补零与保留小数

sprintf() 根据格式和值拼出一个字符串:sprintf('%05.2f', 3.14159) 返回 "03.14"。学习 %s、%d 和 %f,补零、固定小数位、对齐、参数编号,以及 printf 和 vsprintf。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

sprintf() 根据一个格式和一组值拼出一个字符串并返回:格式里的每个 % 占位符依次被下一个值替换。sprintf('%s is %d years old', 'Ada', 36) 返回 "Ada is 36 years old"。printf() 接收同样的参数,但它直接打印结果,而不是返回结果。

占位符按从左到右的顺序依次填入。%.2f 总是显示两位小数(4.50,而不是 4.5),%05d 用零把数字补足到五位。

格式说明符

一个占位符由 %、可选的修饰符和一个表示类型的字母组成:

说明符含义sprintf(...)结果
%s字符串sprintf('%s', 'PHP')PHP
%d整数(有符号)sprintf('%d', 42.9)42
%f浮点数,默认 6 位小数sprintf('%f', 1.5)1.500000
%.2f浮点数,2 位小数sprintf('%.2f', 1.5)1.50
%e科学计数法sprintf('%e', 1234.5678)1.234568e+3
%x / %X十六进制sprintf('%x', 255)ff
%o八进制sprintf('%o', 8)10
%b二进制sprintf('%b', 5)101
%c由编码得到的字符sprintf('%c', 65)A
%u无符号整数sprintf('%u', 3)3
%%百分号本身sprintf('%d%%', 50)50%

改一下下面的值,再运行一次:

%d 会把浮点数向零截断,所以 42.9 变成 42。如果想得到 43,先四舍五入:sprintf('%d', round(42.9))。不是数字的字符串(比如 'abc')在 %d 下会变成 0。

用前导零补位

在 % 和字母之间可以放一个填充字符和一个宽度。%05d 的意思是“用 0 补足到 5 位宽”。格式化订单号、发票编号、时间和日期通常就这么写。

宽度是最小值。比宽度更长的数字会完整打印出来。

%05.2f:宽度和小数位一起用

对浮点数来说,宽度计算的是结果的所有字符,包括小数点和负号。所以 %05.2f 作用于 3.14159 得到 03.14:一共五个字符,其中两个在小数点后面。

%f 使用当前区域设置(用 setlocale() 设置)的小数点,而 %F 始终使用点号。如果你的代码设置了区域,而 JSON、CSV 或 API 又需要点号,就用 %F。

按列对齐文本

正数宽度表示右对齐,宽度前加 - 表示左对齐,' 后面跟一个字符可以指定自定义填充字符。把它们组合起来,就能排出整齐的纯文本报表和小票。

%-14s 在商品名右侧补空格到 14 个字符,%8.2f 把价格在 8 个字符内右对齐,%'-27s 配合空字符串打印出一行 27 个短横线。%'*10s 用 * 代替空格填充。

给参数编号,重复使用或调换顺序

%1$s 表示“第一个参数,作为字符串”,%2$d 表示“第二个参数,作为整数”。有了编号占位符,你可以重复使用一个值,或者在不改参数列表的情况下调换顺序。当不同语言的语序不一样时,翻译人员正需要这一点。

vsprintf、printf 和返回值

vsprintf() 以一个数组的形式接收所有值,值本来就放在数组里时很方便。printf() 返回它打印的字节数,vprintf() 是 printf() 的数组版本。

printf() 返回的计数包含换行符,所以 "Hello\n" 是 6 个字节。对于多字节文本,它数的是字节,而不是字符。

参数太少会抛出错误

从 PHP 8 开始,如果格式里的占位符比值多,会抛出 ArgumentCountError,而不是返回 false。遇到这个错误时,数一数 % 占位符的个数(%% 不算)。

错误信息把格式字符串也算作一个参数:ArgumentCountError: 4 arguments are required, 3 given。多余的参数会被悄悄忽略,所以反过来的错误不会报错。如果 sprintf 的结果看起来不对,把格式和值并排打印出来对照。如果你只需要千位分隔符,用 number_format() 比用 sprintf 自己拼要简单。完整的修饰符列表见 php.net。

常见问题

PHP 中怎么给数字加前导零?

用 sprintf('%05d', 42),它返回 "00042"。0 是填充字符,5 是总宽度。对字符串来说,str_pad('42', 5, '0', STR_PAD_LEFT) 得到同样的结果。

怎么用 sprintf 把数字保留 2 位小数?

用 %.2f:sprintf('%.2f', 3.14159) 返回 "3.14",sprintf('%.2f', 5) 返回 "5.00"。再加上宽度还能同时补零:%08.2f 得到 "00003.14"。

PHP 中 printf 和 sprintf 有什么区别?

sprintf() 返回格式化后的字符串,方便你保存起来。printf() 直接把它打印出来,并返回打印的字节数。echo sprintf(...) 和 printf(...) 的输出完全相同。

PHP 中 %s 是什么意思?

%s 是 sprintf() 和 printf() 里字符串的占位符:sprintf('Hello, %s', 'Ada') 返回 "Hello, Ada"。传给 %s 的数字会被转换成字符串。%d 用于整数,%f 用于浮点数。

sprintf 中怎么重复使用同一个参数?

给占位符编号:sprintf('%1$s loves %2$s, and %2$s loves %1$s', 'Ada', 'PHP')。格式字符串要用单引号:在双引号里,PHP 会把 $s 当成变量,于是 "%1$s" 变成 %1 后面跟着 $s 的值。

Coddy 编程语言插图

和 Coddy 一起学编程

开始