note 55837 added to function.sprintf

From: Date: Mon, 15 Aug 2005 04:47:58 +0000
Subject: note 55837 added to function.sprintf
Groups: php.notes 
Request: Send a blank email to php-notes+get-93660@lists.php.net to get a copy of this message
trying to fix the multibyte non-compliance of sprintf, I came to that : <?php function mb_sprintf($format) { $argv = func_get_args() ; array_shift($argv) ; return mb_vsprintf($format, $argv) ; } function mb_vsprintf($format, $argv) { $newargv = array() ; preg_match_all("\%('.+|[0 ]|)([1-9][0-9]*|)sU", $format, $results, PREG_SET_ORDER) ; foreach($results as $result) { list($string_format, $filler, $size) = $result ; if(strlen($filler)>1) $filler = substr($filler, 1) ; while(!is_string($arg = array_shift($argv))) $newargv[] = $arg ; $pos = strpos($format, $string_format) ; $format = substr($format, 0, $pos) . ($size ? str_repeat($filler, $size-strlen($arg)) : '') . str_replace('%', '%%', $arg) . substr($format, $pos+strlen($string_format)) ; } return vsprintf($format, $newargv) ; } ?> handle with care : 1. that function was designed mostly for utf-8. i guess it won't work with any static mb encoding. 2. my configuration sets the mbstring.func_overload configuration directive to 7, so you may wish to replace substr, strlen, etc. with mb_* equivalents. 3. since preg_* doesn't complies with mb strings, I used a '.+' in the regexp to symbolize an escaped filler character. That means, %'xy5s pattern will match, unfortunately. It is recomended to remove the '+', unless you are intending to use an mb char as filler. 4. the filler fills at left, and only at left. 5. I couldn't succeed with a preg_replace thing : the problem was to use the differents lengths of the string arguements in the same replacement, string or callback. That's why the code is much longuer than I expected. 6. The pattern wil not match any %1\$s thing... just was too complicated for me. 7. Although it has been tested, and works fine within the limits above, this is much more a draft than a end-user function. I would enjoy any improvment. The test code below shows possibilities, and explains the problem that occures with an mb string argument in sprintf. <?php header("content-type:text/plain; charset=UTF-8") ; $mb_string = "xéxàx" ; echo sprintf("%010s", $mb_string), " [octet-size: ", str_sizeof($mb_string) , " ; count: ", strlen(sprintf("%010s", $mb_string)), " characters]\n" ; echo mb_sprintf("%010s", $mb_string), " [octet-size: ", str_sizeof($mb_string) , " ; count: ", strlen(mb_sprintf("%010s", $mb_string)), " characters]\n" ; echo "\n" ; echo mb_sprintf("%''10s\n%'010s\n%'û10s\n%10d\n%'x10s\n%010s\n% 10s\n%010s\n%'1s\n", "zero", "one", "two", 3, "four", "ƒîve", "%s%i%x", "šéveñ", "eight") ; ?> ---- Manual Page -- http://www.php.net/manual/en/function.sprintf.php Edit -- http://master.php.net/manage/user-notes.php?action=edit+55837 Delete: added to the manual -- http://master.php.net/manage/user-notes.php?action=delete+55837&report=yes&reason=added+to+the+manual Delete: bad code -- http://master.php.net/manage/user-notes.php?action=delete+55837&report=yes&reason=bad+code Delete: spam -- http://master.php.net/manage/user-notes.php?action=delete+55837&report=yes&reason=spam Delete: useless -- http://master.php.net/manage/user-notes.php?action=delete+55837&report=yes&reason=useless Delete: non-english -- http://master.php.net/manage/user-notes.php?action=delete+55837&report=yes&reason=non-english Delete: other reasons -- http://master.php.net/manage/user-notes.php?action=delete+55837&report=yes Reject -- http://master.php.net/manage/user-notes.php?action=reject+55837&report=yes Search -- http://master.php.net/manage/user-notes.php

« previous php.notes (#93660) next »