PHP Conference Japan 2024

sprintf

(PHP 4, PHP 5, PHP 7, PHP 8)

sprintf傳回格式化的字串

說明

sprintf(字串 $format, 混合 ...$values): 字串

根據格式字串 format 產生並傳回字串。

參數

format

格式字串由零或多個指示組成:直接複製到結果的普通字元(不包括 %)和轉換規範,每個轉換規範都會提取自己的參數。

轉換規範遵循以下原型:%[argnum$][flags][width][.precision]specifier

Argnum

後面跟著美元符號 $ 的整數,用於指定在轉換中要處理哪個數字參數。

Flags
旗標 說明
- 在給定的欄位寬度內向左對齊;預設為向右對齊
+ 在正數前加上加號 +;預設情況下,只有負數會加上負號。
(空格) 使用空格填充結果。這是預設值。
0 僅使用零左邊填充數字。使用 s 指定符號時,也可以使用零右邊填充。
'(字元) 使用字元 (char) 填充結果。

Width

一個表示此轉換應產生的最小字元數的整數,或 *。如果使用 *,則寬度會以額外的整數值提供,該值會置於指定符號格式化的值前面。

Precision

一個句點 .,後面可選擇跟隨一個整數或 *,其含義取決於指定符號

  • 對於 eEfF 指定符號:這是要列印在小數點後的位數(預設情況下為 6)。
  • 對於 gGhH 指定符號:這是要列印的最大有效位數。
  • 對於 s 指定符號:它充當截止點,設定字串的最大字元限制。

注意 如果指定了句點但沒有明確的精確值,則假設為 0。如果使用 *,則精確度會以額外的整數值提供,該值會置於指定符號格式化的值前面。

指定符號
指定符號 說明
% 一個字面的百分比符號。不需要引數。
b 引數會被視為整數並以二進位數表示。
c 引數會被視為整數並以具有該 ASCII 碼的字元表示。
d 引數會被視為整數並以(帶符號)十進位數表示。
e 引數會被視為科學記號表示法(例如 1.2e+2)。
E e 指定符號類似,但使用大寫字母(例如 1.2E+2)。
f 引數會被視為浮點數並以浮點數表示(感知地區設定)。
F 引數會被視為浮點數並以浮點數表示(不感知地區設定)。
g

通用格式。

讓 P 等於精確度(如果非零),如果省略精確度,則為 6,如果精確度為零,則為 1。然後,如果使用 E 樣式的轉換的指數為 X

如果 P > X ≥ −4,則轉換使用 f 樣式和 P − (X + 1) 精確度。否則,轉換使用 e 樣式和 P − 1 精確度。

G g 指定符號類似,但使用 Ef
h g 指定符號類似,但使用 F。自 PHP 8.0.0 起可用。
H g 指定符號類似,但使用 EF。自 PHP 8.0.0 起可用。
o 引數會被視為整數並以八進位數表示。
s 引數會被視為並以字串表示。
u 引數會被視為整數並以無符號十進位數表示。
x 引數會被視為整數並以十六進位數表示(使用小寫字母)。
X 引數會被視為整數並以十六進位數表示(使用大寫字母)。

警告

c 類型指定符號會忽略填充和寬度。

警告

嘗試將字串和寬度指定符號與每個字元需要多個位元組的字元集組合使用,可能會導致意外的結果。

變數將會強制轉換為適合指定符號的類型

類型處理
類型 指定符號
字串 s
整數 ducoxXb
浮點數 eEfFgGhH

values

傳回值

根據格式字串 format 產生並傳回字串。

錯誤/例外

從 PHP 8.0.0 開始,如果引數的數量為零,則會拋出 ValueError。在 PHP 8.0.0 之前,會改為發出 E_WARNING

從 PHP 8.0.0 開始,如果 [width] 小於零或大於 PHP_INT_MAX,則會拋出 ValueError。在 PHP 8.0.0 之前,會改為發出 E_WARNING

從 PHP 8.0.0 開始,如果 [precision] 小於零或大於 PHP_INT_MAX,則會拋出 ValueError。在 PHP 8.0.0 之前,會改為發出 E_WARNING

從 PHP 8.0.0 開始,當提供的引數少於所需引數時,會拋出 ArgumentCountError。在 PHP 8.0.0 之前,會傳回 false 並改為發出 E_WARNING

更新日誌

版本 說明
8.0.0 此函式在失敗時不再傳回 false
8.0.0 如果引數數量為零,則會拋出 ValueError;先前此函式會改為發出 E_WARNING
8.0.0 如果 [width] 小於零或大於 PHP_INT_MAX,則會拋出 ValueError;先前此函式會改為發出 E_WARNING
8.0.0 如果 [precision] 小於零或大於 PHP_INT_MAX,則會拋出 ValueError;先前此函式會改為發出 E_WARNING
8.0.0 當提供的引數少於所需引數時,會拋出 ArgumentCountError;先前此函式會改為發出 E_WARNING

範例

範例 #1 引數交換

格式字串支援引數編號/交換。

<?php
$num
= 5;
$location = 'tree';

$format = 'There are %d monkeys in the %s';
echo
sprintf($format, $num, $location);
?>

上述範例將會輸出

There are 5 monkeys in the tree

然而,假設我們在單獨的檔案中建立格式字串,通常是因為我們想要將其國際化,並將其重寫為

<?php
$format
= 'The %s contains %d monkeys';
echo
sprintf($format, $num, $location);
?>

現在我們遇到一個問題。格式字串中的佔位符順序與程式碼中的參數順序不符。我們希望保持程式碼原樣,僅在格式字串中指明佔位符對應的參數。我們應該這樣寫格式字串:

<?php
$format
= 'The %2$s contains %1$d monkeys';
echo
sprintf($format, $num, $location);
?>

這樣做還有一個額外的好處,就是可以重複使用佔位符,而無需在程式碼中添加更多參數。

<?php
$format
= 'The %2$s contains %1$d monkeys.
That\'s a nice %2$s full of %1$d monkeys.'
;
echo
sprintf($format, $num, $location);
?>

當使用參數交換時,n$ *位置指定符* 必須緊接在百分比符號(%)之後,在任何其他指定符之前,如下所示。

範例 #2 指定填充字元

<?php
echo sprintf("%'.9d\n", 123);
echo
sprintf("%'.09d\n", 123);
?>

上述範例將會輸出

......123
000000123

範例 #3 位置指定符與其他指定符

<?php
$format
= 'The %2$s contains %1$04d monkeys';
echo
sprintf($format, $num, $location);
?>

上述範例將會輸出

The tree contains 0005 monkeys

範例 #4 sprintf():以零填充的整數

<?php
$isodate
= sprintf("%04d-%02d-%02d", $year, $month, $day);
?>

範例 #5 sprintf():格式化貨幣

<?php
$money1
= 68.75;
$money2 = 54.35;
$money = $money1 + $money2;
echo
$money;
echo
"\n";
$formatted = sprintf("%01.2f", $money);
echo
$formatted;
?>

上述範例將會輸出

123.1
123.10

範例 #6 sprintf():科學記號表示法

<?php
$number
= 362525200;

echo
sprintf("%.3e", $number);
?>

上述範例將會輸出

3.625e+8

參見

新增註解

使用者貢獻的註解 35 則註解

remy dot damour at -please-no-spam-laposte dot net
15 年前
在使用 printf() 和 sprintf() 函數時,跳脫字元不是反斜線 '\',而是 '%'。

也就是說,要印出 '%' 字元,您需要用它本身跳脫它
<?php
printf
('%%%s%%', 'koko'); #output: '%koko%'
?>
Alex R. Gibbs
11 年前
1. 加號 ('+') 表示在正數前放置 '+',而減號 ('-') 表示靠左對齊。文件錯誤地說明它們是可以互換的。它們會產生可以組合的獨特結果

<?php
echo sprintf ("|%+4d|%+4d|\n", 1, -1);
echo
sprintf ("|%-4d|%-4d|\n", 1, -1);
echo
sprintf ("|%+-4d|%+-4d|\n", 1, -1);
?>

輸出

| +1| -1|
|1 |-1 |
|+1 |-1 |

2. 用 '0' 填充與用其他字元填充不同。零只會被新增到數字的前面,在任何符號之後。其他字元將被新增到符號之前或數字之後

<?php
echo sprintf ("|%04d|\n", -2);
echo
sprintf ("|%':4d|\n", -2);
echo
sprintf ("|%-':4d|\n", -2);

// 指定 "-" 和 "0" 會造成衝突,產生非預期的結果:
echo sprintf ("|%-04d|\n", -2);

// 用其他數字填充的行為與其他非零字元類似:
echo sprintf ("|%-'14d|\n", -2);
echo
sprintf ("|%-'04d|\n", -2);
?>

輸出

|-002|
|::-2|
|-2::|
|-2 |
|-211|
|-2 |
timo dot frenay at gmail dot com
13 年前
以下是如何印出具有 16 個有效位數的浮點數,而不論其大小

<?php
$result
= sprintf(sprintf('%%.%dF', max(15 - floor(log10($value)), 0)), $value);
?>

這比執行類似 sprintf('%.15F', $value) 的操作更可靠,因為後者可能會截斷非常小數字的有效位數,或者對於非常大的數字會印出虛假的數字(意味著超出浮點數中可可靠表示的額外位數)。
kontakt at myseosolution dot de
9 年前
關於使用 sprintf 強制前導零已經有一些註解,但範例只包含整數。我需要在浮點數上使用前導零,並且很驚訝它沒有如預期般運作。

範例
<?php
sprintf
('%02d', 1);
?>

這會產生 01。但是,嘗試對具有精度的浮點數執行相同的操作是行不通的

<?php
sprintf
('%02.2f', 1);
?>

產生 1.00。

這讓我有點摸不著頭緒。若要獲得想要的結果,需要新增精度 (2) 和小數分隔符 "." (1) 的長度。因此,正確的模式將是

<?php
sprintf
('%05.2f', 1);
?>

輸出:01.00

如需更詳細的說明,請參閱 http://stackoverflow.com/a/28739819/413531
Anonymous
2 年前
如果格式字串用雙引號 ("") 括起來,則需要在 argnum 之後使用反斜線字元 (\) 跳脫錢字符號,像這樣 %1\$s,以便 PHP 不會嘗試將其解釋為變數。像這樣使用反斜線稱為跳脫序列。

<?php
// 範例字串
$number = 499;
$format = "不含小數點的數字:%1\$d,以及含兩位小數點的數字:%1\$.2f";

// 格式化並印出字串
printf($format, $number);
?>
Anonymous
7 年前
當嘗試重構具有重複佔位符的較長字串時,請小心,例如

sprintf("嗨 %s。你的名字是 %s", $name, $name);

使用引數編號

sprintf("嗨 %1$s。你的名字是 %1$s", $name);

這會在**執行階段**炸裂,因為 `$s` 會被當作變數處理。如果沒有 `$s` 可以替換,會拋出通知。

解決方案是在字串中使用單引號來防止變數替換

sprintf('嗨 %1$s。你的名字是 %1$s', $name);

如果需要變數替換,則需要分割字串,並將其保留在單引號中

sprintf("嗨 " . '%1$s' . ". 你的 {$variable} 是 " . '%1$s', $name);
viktor at textalk dot com
15 年前
一個更完整且可運作的 mb_sprintf 和 mb_vsprintf 版本。它應該適用於任何「保留 ASCII」的編碼,例如 UTF-8 和所有 ISO-8859 字元集。它可以處理符號、填充、對齊、寬度和精確度。不處理引數交換。

<?php
if (!function_exists('mb_sprintf')) {
function
mb_sprintf($format) {
$argv = func_get_args() ;
array_shift($argv) ;
return
mb_vsprintf($format, $argv) ;
}
}
if (!
function_exists('mb_vsprintf')) {
/**
* 適用於格式和引數中的所有編碼。
* 支援:符號、填充、對齊、寬度和精確度。
* 不支援:引數交換。
*/
function mb_vsprintf($format, $argv, $encoding=null) {
if (
is_null($encoding))
$encoding = mb_internal_encoding();

// 在格式中使用 UTF-8,以便我們可以使用 preg_split 中的 u 標誌
$format = mb_convert_encoding($format, 'UTF-8', $encoding);

$newformat = ""; // 以 UTF-8 建立新的格式
$newargv = array(); // 未處理的引數保持不變的編碼

while ($format !== "") {

// 將格式分割成兩個部分:$pre 和 $post,以第一個 % 指示符分割
// 我們也取得匹配的群組
list ($pre, $sign, $filler, $align, $size, $precision, $type, $post) =
preg_split("!\%(\+?)('.|[0 ]|)(-?)([1-9][0-9]*|)(\.[1-9][0-9]*|)([%a-zA-Z])!u",
$format, 2, PREG_SPLIT_DELIM_CAPTURE) ;

$newformat .= mb_convert_encoding($pre, $encoding, 'UTF-8');

if (
$type == '') {
// 沒有匹配。什麼都不做。這是最後一次迭代。
}
elseif (
$type == '%') {
// 一個跳脫的 %
$newformat .= '%%';
}
elseif (
$type == 's') {
$arg = array_shift($argv);
$arg = mb_convert_encoding($arg, 'UTF-8', $encoding);
$padding_pre = '';
$padding_post = '';

// 截斷 $arg
if ($precision !== '') {
$precision = intval(substr($precision,1));
if (
$precision > 0 && mb_strlen($arg,$encoding) > $precision)
$arg = mb_substr($precision,0,$precision,$encoding);
}

// 定義填充
if ($size > 0) {
$arglen = mb_strlen($arg, $encoding);
if (
$arglen < $size) {
if(
$filler==='')
$filler = ' ';
if (
$align == '-')
$padding_post = str_repeat($filler, $size - $arglen);
else
$padding_pre = str_repeat($filler, $size - $arglen);
}
}

// 跳脫 % 並將其轉發
$newformat .= $padding_pre . str_replace('%', '%%', $arg) . $padding_post;
}
else {
// 另一種類型,轉發
$newformat .= "%$sign$filler$align$size$precision$type";
$newargv[] = array_shift($argv);
}
$format = strval($post);
}
// 將新的格式從 UTF-8 轉換回原始編碼
$newformat = mb_convert_encoding($newformat, $encoding, 'UTF-8');
return
vsprintf($newformat, $newargv);
}
}
?>
nate at frickenate dot com
15 年前
這是一個乾淨、可運作的函式版本,允許使用命名引數而不是數字引數。例如:不用 sprintf('%1$s', 'Joe');,我們可以改用 sprintf('%name$s', array('name' => 'Joe'));。我提供了 2 個不同的版本:第一個使用類似 php 的語法 (例如:%name$s),而第二個使用 python 語法 (例如:%(name)s)。

<?php

/**
* sprintf 的版本,用於需要使用具名參數的情況(php 語法)
*
* 使用 sprintf: sprintf('second: %2$s ; first: %1$s', '1st', '2nd');
*
* 使用 sprintfn: sprintfn('second: %second$s ; first: %first$s', array(
* 'first' => '1st',
* 'second'=> '2nd'
* ));
*
* @param string $format sprintf 格式字串,帶有任意數量的具名參數
* @param array $args 要進行替換的 ['arg_name' => 'arg value', ... ] 陣列
* @return string|false sprintf 呼叫的結果,或發生錯誤時返回布林值 false
*/
function sprintfn ($format, array $args = array()) {
// 參數名稱對應到 sprintf 數字參數值的映射
$arg_nums = array_slice(array_flip(array_keys(array(0 => 0) + $args)), 1);

// 尋找下一個具名參數。每次搜尋都從前一個替換的結尾開始。
for ($pos = 0; preg_match('/(?<=%)([a-zA-Z_]\w*)(?=\$)/', $format, $match, PREG_OFFSET_CAPTURE, $pos);) {
$arg_pos = $match[0][1];
$arg_len = strlen($match[0][0]);
$arg_key = $match[1][0];

// 程式設計師沒有為格式字串中找到的具名參數提供值
if (! array_key_exists($arg_key, $arg_nums)) {
user_error("sprintfn(): 缺少參數 '${arg_key}'", E_USER_WARNING);
return
false;
}

// 使用對應的數字參數替換具名參數
$format = substr_replace($format, $replace = $arg_nums[$arg_key], $arg_pos, $arg_len);
$pos = $arg_pos + strlen($replace); // 跳到替換的結尾以進行下一次迭代
}

return
vsprintf($format, array_values($args));
}

/**
* sprintf 的版本,用於需要使用具名參數的情況(python 語法)
*
* 使用 sprintf: sprintf('second: %2$s ; first: %1$s', '1st', '2nd');
*
* 使用 sprintfn: sprintfn('second: %(second)s ; first: %(first)s', array(
* 'first' => '1st',
* 'second'=> '2nd'
* ));
*
* @param string $format sprintf 格式字串,帶有任意數量的具名參數
* @param array $args 要進行替換的 ['arg_name' => 'arg value', ... ] 陣列
* @return string|false sprintf 呼叫的結果,或發生錯誤時返回布林值 false
*/
function sprintfn ($format, array $args = array()) {
// 參數名稱對應到 sprintf 數字參數值的映射
$arg_nums = array_slice(array_flip(array_keys(array(0 => 0) + $args)), 1);

// 尋找下一個具名參數。每次搜尋都從前一個替換的結尾開始。
for ($pos = 0; preg_match('/(?<=%)\(([a-zA-Z_]\w*)\)/', $format, $match, PREG_OFFSET_CAPTURE, $pos);) {
$arg_pos = $match[0][1];
$arg_len = strlen($match[0][0]);
$arg_key = $match[1][0];

// 程式設計師沒有為格式字串中找到的具名參數提供值
if (! array_key_exists($arg_key, $arg_nums)) {
user_error("sprintfn(): 缺少參數 '${arg_key}'", E_USER_WARNING);
return
false;
}

// 使用對應的數字參數替換具名參數
$format = substr_replace($format, $replace = $arg_nums[$arg_key] . '$', $arg_pos, $arg_len);
$pos = $arg_pos + strlen($replace); // 跳到替換的結尾以進行下一次迭代
}

return
vsprintf($format, array_values($args));
}

?>
ian dot w dot davis at gmail dot com
19 年前
只是要詳細說明 downright 關於 %f 不同含義的觀點,看起來行為在 4.3.7 版時發生了顯著變化,而不僅僅是在不同的平台上不同。以前,寬度指定符給出了小數點「之前」允許的字元數。現在,寬度指定符給出了「總共」的字元數。(這與其他語言中 printf() 的語義一致。)請參閱錯誤 #28633 和 #29286 以了解更多詳細資訊。
jfgrissom at gmail dot com
15 年前
我為了尋找一個 32 位元數字的二補數而經歷了一場惡夢。

我從 http://www.webmasterworld.com/forum88/13334.htm 取得這個(功勞歸於應得的人... =P)

引述:...找出任何數字的二補數,即 -(pow(2, n) - N),其中 n 是位數,而 N 是要找出其二補數的數字。

這對我來說簡直是魔法...之前我試著使用

sprintf ("%b",$32BitDecimal);
但是當 $32BitDecimal 的值超過 2,000,000,000 時,它總是返回 10000000000000000000000。

這個 -(pow(2, n) - N)
效果非常好,而且非常準確。

希望這能幫助在 PHP 中與二補數奮戰的人。
dwieeb at gmail dot com
14 年前
如果您使用預設的填充指定符(一個空格),然後將其列印到 HTML,您會注意到 HTML 無法正確顯示多個空格。這是因為任何空白字元的序列都被視為一個空格。

為了克服這個問題,我編寫了一個簡單的函式,將 sprintf() 返回的字串中的所有空格替換為字元實體參考 "&nbsp;",以在 sprintf() 返回的字串中實現不間斷空格

<?php
//以下是函式:
function sprintf_nbsp() {
$args = func_get_args();
return
str_replace(' ', '&nbsp;', vsprintf(array_shift($args), array_values($args)));
}

//用法(完全像 sprintf):
$format = 'The %d monkeys are attacking the [%10s]!';
$str = sprintf_nbsp($format, 15, 'zoo');
echo
$str;
?>

上述範例將會輸出
那 15 隻猴子正在攻擊 [ zoo]!

<?php
//列印字串而不是返回字串的變體:
function printf_nbsp() {
$args = func_get_args();
echo
str_replace(' ', '&nbsp;', vsprintf(array_shift($args), array_values($args)));
}
?>
krzysiek dot 333 at gmail dot com - zryty dot hekko dot pl
13 年前
將 IP 位址編碼和解碼為格式:1A2B3C4D(mysql 資料行:char(8))

<?php
function encode_ip($dotquad_ip)
{
$ip_sep = explode('.', $dotquad_ip);
return
sprintf('%02x%02x%02x%02x', $ip_sep[0], $ip_sep[1], $ip_sep[2], $ip_sep[3]);
}

function
decode_ip($int_ip)
{
$hexipbang = explode('.', chunk_split($int_ip, 2, '.'));
return
hexdec($hexipbang[0]). '.' . hexdec($hexipbang[1]) . '.' . hexdec($hexipbang[2]) . '.' . hexdec($hexipbang[3]);
}
?>
php at mikeboers dot com
16 年前
延續之前基於鍵值的 sprintf 主題...

我大致上(我看到有幾個情況會有點奇怪)複製了 Python 使用字典進行字串格式化的語法。相較於過去幾次的嘗試,這次的改進之處在於它仍然尊重所有的格式化選項,正如你在我的範例中所見。

而且錯誤處理非常糟糕(只是一個 echo)。我只是把它拼湊在一起,所以你可以隨意使用。 =]

<?php

function sprintf_array($string, $array)
{
$keys = array_keys($array);
$keysmap = array_flip($keys);
$values = array_values($array);

while (
preg_match('/%\(([a-zA-Z0-9_ -]+)\)/', $string, $m))
{
if (!isset(
$keysmap[$m[1]]))
{
echo
"No key $m[1]\n";
return
false;
}

$string = str_replace($m[0], '%' . ($keysmap[$m[1]] + 1) . '$', $string);
}

array_unshift($values, $string);
var_dump($values);
return
call_user_func_array('sprintf', $values);
}

echo
sprintf_array('4 digit padded number: %(num)04d ', array('num' => 42));

?>

乾杯!
carmageddon at gmail dot com
13 年前
如果你想將十進制(整數)數字轉換為固定長度的二進制數字,例如 9 位元,請使用這個

$binary = sprintf('%08b', $number );

例如
<?php
$bin
= sprintf('%08b',511 );
echo
$bin."\n";
?>

會輸出 111111111
而 2 會輸出 00000010

我知道前導零對我很有用,也許對其他人也一樣。
no dot email dot address at example dot com
22 年前
在 sprintf() 中使用參數交換與 gettext:假設你已經撰寫了以下腳本

<?php
$var
= sprintf(gettext("The %2\$s contains %1\$d monkeys"), 2, "cage");
?>

現在你執行 xgettext 以產生 .po 檔案。.po 檔案將會像這樣

#: file.php:9
#, ycp-format
msgid "The %2\\$s contains %1\\$d monkeys"
msgstr ""

請注意,xgettext 已新增了一個額外的反斜線。

一旦你翻譯了字串,你必須從 ID 字串以及翻譯中刪除所有反斜線,因此 po 檔案會像這樣

#: file.php:9
#, ycp-format
msgid "The %2$s contains %1$d monkeys"
msgstr "Der er %1$d aber i %2$s"

現在執行 msgfmt 以產生 .mo 檔案,如果需要,重新啟動 Apache 以移除 gettext 快取,你就可以開始了。
Pacogliss
19 年前
只是提醒初學者:範例 6 'printf("[%10s]\n", $s);' 只有在你放置 html '<pre></pre>' 標籤時才會運作(也就是顯示出空格)(省時的網頁抓取技巧 ;-)。
geertdd at gmail dot com
14 年前
請注意,當使用符號指定符時,數字零被視為正數,並且會在前面加上 "+" 符號。

<?php
printf
('%+d', 0); // +0
?>
abiltcliffe at bigfoot.com
22 年前
給 jrust at rustyparts.com,請注意,如果你使用雙引號字串並且*沒有*用反斜線跳脫貨幣符號,$s 和 $d 會被解釋為變數參考。反斜線本身不是格式指定符的一部分,但當你撰寫格式字串時,你需要包含它(除非你使用單引號)。
john at jbwalker dot com
10 年前
我無法在上面的文件中找到應該是警告的資訊,如果你的指定符比要匹配的變數還多,sprintf 會傳回「沒有東西」。我認為這個事實也應該在傳回值下註明。
Anderson
5 年前
過去對我幫助很大的「猴子」範例很遺憾地消失了。

我會在評論中重新發布它作為一個回憶。

<?php
$n
= 43951789;
$u = -43951789;
$c = 65; // ASCII 65 是 'A'

// 注意雙 %%,這會印出一個字面上的 '%' 字元
printf("%%b = '%b'\n", $n); // 二進位表示法
printf("%%c = '%c'\n", $c); // 印出 ASCII 字元,與 chr() 函式相同
printf("%%d = '%d'\n", $n); // 標準整數表示法
printf("%%e = '%e'\n", $n); // 科學記號表示法
printf("%%u = '%u'\n", $n); // 正整數的無號整數表示法
printf("%%u = '%u'\n", $u); // 負整數的無號整數表示法
printf("%%f = '%f'\n", $n); // 浮點數表示法
printf("%%o = '%o'\n", $n); // 八進位表示法
printf("%%s = '%s'\n", $n); // 字串表示法
printf("%%x = '%x'\n", $n); // 十六進位表示法 (小寫)
printf("%%X = '%X'\n", $n); // 十六進位表示法 (大寫)

printf("%%+d = '%+d'\n", $n); // 正整數的符號指定子
printf("%%+d = '%+d'\n", $u); // 負整數的符號指定子

/*
%b = '10100111101010011010101101'
%c = 'A'
%d = '43951789'
%e = '4.395179e+7'
%u = '43951789'
%u = '18446744073665599827'
%f = '43951789.000000'
%o = '247523255'
%s = '43951789'
%x = '29ea6ad'
%X = '29EA6AD'
%+d = '+43951789'
%+d = '-43951789'
*/

$s = 'monkey';
$t = 'many monkeys';

printf("[%s]\n", $s); // 標準字串輸出
printf("[%10s]\n", $s); // 使用空格靠右對齊
printf("[%-10s]\n", $s); // 使用空格靠左對齊
printf("[%010s]\n", $s); // 零填充也適用於字串
printf("[%'#10s]\n", $s); // 使用自訂的填充字元 '#'
printf("[%10.10s]\n", $t); // 靠左對齊,但限制為 10 個字元

/*
[monkey]
[ monkey]
[monkey ]
[0000monkey]
[####monkey]
[many monke]
*/
?>
php at sharpdreams dot com
20 年前
請注意,當使用參數交換時,您必須為每個參數編號,否則 sprintf 會混亂。只有在您先使用編號參數,然後切換到未編號的參數,再切換回編號參數時才會發生這種情況。

<?php
$sql
= sprintf( "select * from %1\$s left join %2\$s on( %1\$s.id = %2\$s.midpoint ) where %1\$s.name like '%%%s%%' and %2\$s.tagname is not null", "table1", "table2", "bob" );
// 無效:
// Sprintf 會抱怨參數不足。
$sql = sprintf( "select * from %1\$s left join %2\$s on( %1\$s.id = %2\$s.midpoint ) where %1\$s.name like '%%%3\$s%%' and %2\$s.tagname is not null", "table1", "table2", "bob" );
// 有效:請注意 %3\$s
?>
Hayley Watson
12 年前
如果您使用參數編號,則具有相同編號的格式指定子會取得相同的參數;這樣可以避免在函式呼叫中重複參數。

<?php

$pattern
= '%1$s %1$\'#10s %1$s!';

printf($pattern, "badgers");
?>
splogamurugan at gmail dot com
15 年前
$format = '在 %s 和 %s 中有 %1$d 隻猴子';
printf($format, 100, 'Chennai', 'Bangalore');

預期輸出
"在 Chennai 和 bangalore 中有 100 隻猴子"

但這會輸出
"在 100 和 Chennai 中有 100 隻猴子"

因為第二和第三個指定子會採用第一個和第二個參數。因為它沒有被賦予任何參數。
hdimac at gmail dot com
10 年前
在範例中,顯示的是 printf,但應該說是 sprintf,這才是正在解釋的函式...只是一個簡單的編輯錯誤。
jrpozo at conclase dot net
19 年前
如果您使用 %f 修飾符來四捨五入小數,請小心,因為它(從 4.3.10 開始)在您設定某些地區設定時將不再產生浮點數,因此您無法累積結果。例如

setlocale(LC_ALL, 'es_ES');
echo(sprintf("%.2f", 13.332) + sprintf("%.2f", 14.446))

會產生 27 而不是 27.78,因此請改用 %F。
Astone
15 年前
當您使用 Google 翻譯時,您必須在「轉換指定子」周圍加上 <span class="notranslate"></span> 來「跳脫」它們。

像這樣

<?php

function getGoogleTranslation($sString, $bEscapeParams = true)
{
// 「跳脫」sprintf 參數
if ($bEscapeParams)
{
$sPatern = '/(?:%%|%(?:[0-9]+\$)?[+-]?(?:[ 0]|\'.)?-?[0-9]*(?:\.[0-9]+)?[bcdeufFosxX])/';
$sEscapeString = '<span class="notranslate">$0</span>';
$sString = preg_replace($sPatern, $sEscapeString, $sString);
}

// 組成資料陣列 (英文到荷蘭文)
$aData = array(
'v' => '1.0',
'q' => $sString,
'langpair' => 'en|nl',
);

// 初始化連線
$rService = curl_init();

// 連線設定
curl_setopt($rService, CURLOPT_URL, 'http://ajax.googleapis.com/ajax/services/language/translate');
curl_setopt($rService, CURLOPT_RETURNTRANSFER, true);
curl_setopt($rService, CURLOPT_POSTFIELDS, $aData);

// 執行請求
$sResponse = curl_exec($rService);

// 關閉連線
curl_close($rService);

// 從 JSON 回應中提取文字
$oResponse = json_decode($sResponse);
if (isset(
$oResponse->responseData->translatedText))
{
$sTranslation = $oResponse->responseData->translatedText;
}
else
{
// 如果發生錯誤,使用原始字串
$sTranslation = $sString;
}

// 取代 "notranslate" 標籤
if ($bEscapeParams)
{
$sEscapePatern = '/<span class="notranslate">([^<]*)<\/span>/';
$sTranslation = preg_replace($sEscapePatern, '$1', $sTranslation);
}

// 回傳結果
return $sTranslation;
}

?>

感謝 MelTraX 定義了正規表示式!
ignat dot scheglovskiy at gmail dot com
12 年前
這是一個範例,說明如何使用對齊、填補和精確度規範來列印格式化的項目清單

<?php

$out
= "The Books\n";
$books = array("Book 1", "Book 2", "Book 3");
$pages = array("123 pages ", "234 pages", "345 pages");
for (
$i = 0; $i < count($books); $i++) {
$out .= sprintf("%'.-20s%'.7.4s\n", $books[$i], $pages[$i]);
}
echo
$out;

// 輸出:
//
// The Books
// Book 1.................123
// Book 2.................234
// Book 3.................345
?>
John Walker
15 年前
關於浮點數問題,我注意到 %f 和 %F 預設似乎會輸出最大 6 位數的精度,因此如果需要更多位數,則必須指定 1.15f (例如)。

在我的情況下,輸入 (來自 MySQL) 是一個具有 15 位數精度的字串,但顯示為 6 位數。可能發生的情況是在顯示之前,轉換為浮點數時會進行四捨五入。將其顯示為 1.15f (或在我的情況下為 %s) 會顯示正確的數字。
scott dot gardner at mac dot com
16 年前
在範例 #6 的最後一個範例中,輸出有錯誤。

printf("[%10.10s]\n", $t); // 左對齊,但截斷為 10 個字元

這會輸出右對齊。

為了輸出左對齊

printf("[%-10.10s]\n", $t);
iannacone
5 個月前
也值得注意的是,Argnum 從 1 開始,而不是 0
Andrew dot Wright at spamsux dot atnf dot csiro dot au
22 年前
我上一個範例中的錯誤
$b = sprintf("%30.s", $a);
只會在 $a 前面新增足夠的空格,以將空格 + strlen($a) 填補到 30 個位置。

我將固定文字置中於 72 個字元寬度空間的方法是

$a = "Some string here";
$lwidth = 36; // 72/2
$b = sprintf("%".($lwidth + round(strlen($a)/2)).".s", $a);
Sam Bull
9 年前
修復 sprintfn 函數的具名引數 (https://php.dev.org.tw/manual/en/function.sprintf.php#94608)

將第一行從
$arg_nums = array_slice(array_flip(array_keys(array(0 => 0) + $args)), 1);
改為
$arg_nums = array_keys($args);
array_unshift($arg_nums, 0);
$arg_nums = array_flip(array_slice($arg_nums, 1, NULL, true));
nmmm at nmmm dot nu
9 年前
php printf 和 sprintf 似乎不支援星號 "*" 格式化。

這是一個範例

printf("%*d\n",3,5);

這只會列印 "d",而不是 "<兩個空格>5"
ivan at php dot net
10 年前
來自 viktor at textalk dot com 的 mb_vsprintf 函數程式碼中存在一個小問題。

在 "截斷 $arg" 區段中,以下這一行
$arg = mb_substr($precision,0,$precision,$encoding);
需要替換為
$arg = mb_substr($arg,0,$precision,$encoding);
Nathan Alan
7 年前
只想補充說明,要從字串中取得剩餘的文字,您需要在 scanf 中將以下內容新增為變數

%[ -~]

範例

sscanf($sql, "[%d,%d]%[ -~]", $sheet_id, $column, $remaining_sql);
To Top