我只是想将$str
修改为5个字符,但不能。
$str = "nü";
echo str_pad($str, 5, "ü"); // give nüü
我知道这是一个unicode问题并且搜索了很多但没有运气。我尝试了一些事情,比如;
echo str_pad($str, 4 + mb_strlen($s), $s);
echo str_pad($str, 5 + mb_strlen($s), $s);
此外,我尝试了此http://www.php.net/manual/de/function.str-pad.php#89754并看到了此https://stackoverflow.com/a/11871948/362780。
有关此问题的任何经验吗?
感谢。
答案 0 :(得分:16)
更简单,更有效。 http://3v4l.org/UnXTF
<?php
function mb_str_pad($str, $pad_len, $pad_str = ' ', $dir = STR_PAD_RIGHT, $encoding = NULL)
{
$encoding = $encoding === NULL ? mb_internal_encoding() : $encoding;
$padBefore = $dir === STR_PAD_BOTH || $dir === STR_PAD_LEFT;
$padAfter = $dir === STR_PAD_BOTH || $dir === STR_PAD_RIGHT;
$pad_len -= mb_strlen($str, $encoding);
$targetLen = $padBefore && $padAfter ? $pad_len / 2 : $pad_len;
$strToRepeatLen = mb_strlen($pad_str, $encoding);
$repeatTimes = ceil($targetLen / $strToRepeatLen);
$repeatedString = str_repeat($pad_str, max(0, $repeatTimes)); // safe if used with valid unicode sequences (any charset)
$before = $padBefore ? mb_substr($repeatedString, 0, (int)floor($targetLen), $encoding) : '';
$after = $padAfter ? mb_substr($repeatedString, 0, (int)ceil($targetLen), $encoding) : '';
return $before . $str . $after;
}
// same random testing...
foreach([STR_PAD_BOTH, STR_PAD_LEFT, STR_PAD_RIGHT] as $padType)
{
echo str_pad("FOO", 11, "aeo", $padType) . "\n";
echo mb_str_pad("FOO", 11, "àèò", $padType, "UTF-8") . "\n";
echo str_pad("FOO", 10, "aeo", $padType) . "\n";
echo mb_str_pad("FOO", 10, "àèò", $padType, "UTF-8") . "\n";
echo str_pad("BAAZ", 11, "aeo", $padType) . "\n";
echo mb_str_pad("BAAZ", 11, "àèò", $padType, "UTF-8") . "\n";
echo str_pad("BAAZ", 10, "aeo", $padType) . "\n";
echo mb_str_pad("BAAZ", 10, "àèò", $padType, "UTF-8") . "\n";
echo str_pad("FOOBAR", 6, "aeo", $padType) . "\n";
echo mb_str_pad("FOOBAR", 6, "àèò", $padType, "UTF-8") . "\n";
echo str_pad("FOOBAR", 1, "aeo", $padType) . "\n";
echo mb_str_pad("FOOBAR", 1, "àèò", $padType, "UTF-8") . "\n";
echo str_pad("FOOBAR", 0, "aeo", $padType) . "\n";
echo mb_str_pad("FOOBAR", 0, "àèò", $padType, "UTF-8") . "\n";
echo str_pad("FOOBAR", -10, "aeo", $padType) . "\n";
echo mb_str_pad("FOOBAR", -10, "àèò", $padType, "UTF-8") . "\n";
echo "--\n";
}
?>
答案 1 :(得分:4)
您需要多字节版本的str_pad()
,如下所示。它的灵感来自source code of str_pad()
。
function mb_str_pad($input, $pad_length, $pad_string = ' ', $pad_type = STR_PAD_RIGHT, $encoding = 'UTF-8')
{
$input_length = mb_strlen($input, $encoding);
$pad_string_length = mb_strlen($pad_string, $encoding);
if ($pad_length <= 0 || ($pad_length - $input_length) <= 0) {
return $input;
}
$num_pad_chars = $pad_length - $input_length;
switch ($pad_type) {
case STR_PAD_RIGHT:
$left_pad = 0;
$right_pad = $num_pad_chars;
break;
case STR_PAD_LEFT:
$left_pad = $num_pad_chars;
$right_pad = 0;
break;
case STR_PAD_BOTH:
$left_pad = floor($num_pad_chars / 2);
$right_pad = $num_pad_chars - $left_pad;
break;
}
$result = '';
for ($i = 0; $i < $left_pad; ++$i) {
$result .= mb_substr($pad_string, $i % $pad_string_length, 1, $encoding);
}
$result .= $input;
for ($i = 0; $i < $right_pad; ++$i) {
$result .= mb_substr($pad_string, $i % $pad_string_length, 1, $encoding);
}
return $result;
}
$str = "nü";
$pad = "ü";
echo mb_str_pad($str, 5, $pad);
答案 2 :(得分:3)
我认为你需要查看更多的php.net(这里:http://php.net/str_pad#111147)。但我改变了一下。
注意:不要忘记在mb_internal_encoding("utf-8");
之前调用此方法。
mb_internal_encoding("utf-8");
function str_pad_unicode($str, $pad_len, $pad_str = ' ', $dir = STR_PAD_RIGHT) {
$str_len = mb_strlen($str);
$pad_str_len = mb_strlen($pad_str);
if (!$str_len && ($dir == STR_PAD_RIGHT || $dir == STR_PAD_LEFT)) {
$str_len = 1; // @debug
}
if (!$pad_len || !$pad_str_len || $pad_len <= $str_len) {
return $str;
}
$result = null;
if ($dir == STR_PAD_BOTH) {
$length = ($pad_len - $str_len) / 2;
$repeat = ceil($length / $pad_str_len);
$result = mb_substr(str_repeat($pad_str, $repeat), 0, floor($length))
. $str
. mb_substr(str_repeat($pad_str, $repeat), 0, ceil($length));
} else {
$repeat = ceil($str_len - $pad_str_len + $pad_len);
if ($dir == STR_PAD_RIGHT) {
$result = $str . str_repeat($pad_str, $repeat);
$result = mb_substr($result, 0, $pad_len);
} else if ($dir == STR_PAD_LEFT) {
$result = str_repeat($pad_str, $repeat);
$result = mb_substr($result, 0,
$pad_len - (($str_len - $pad_str_len) + $pad_str_len))
. $str;
}
}
return $result;
}
$t = STR_PAD_LEFT;
$s = '...';
$as = 'AO';
$ms = 'ÄÖ';
echo "<pre>\n";
for ($i = 3; $i <= 1000; $i++) {
$s1 = str_pad($s, $i, $as, $t); // can not inculde unicode char!!!
$s2 = str_pad_unicode($s, $i, $ms, $t);
$l1 = strlen($s1);
$l2 = mb_strlen($s2);
echo "len $l1: $s1 \n";
echo "len $l2: $s2 \n";
echo "\n";
if ($l1 != $l2) die("Fail!");
}
echo "</pre>";
答案 3 :(得分:1)
注意: 这不是对 user2032610 原始问题的准确答案。 但它会在情况下有所帮助,如果您不需要用 unicode 字符填充字符串,而是用空格、点等填充字符串。 (我把它放在这里是因为我正在寻找解决方案,找不到简单的解决方案。它可能会帮助其他类似情况的人。)
$str = "nü";
echo "nü" . str_pad('', 5 - mb_strlen($str), ".");
结果:nü...
答案 4 :(得分:0)
尝试这个(它可能看起来像失败的那个,但它也有编码检查):
<?php
function mb_str_pad ($input, $pad_length, $pad_string, $pad_style, $encoding="UTF-8") {
return str_pad($input, strlen($input)-mb_strlen($input,$encoding)+$pad_length, $pad_string, $pad_style);
}
?>
答案 5 :(得分:0)
function mb_str_pad($str,$pad,$pad_str,$pad_type = STR_PAD_RIGHT,$encoding = 'UTF-8'){
$result = null;
$length = mb_strlen($str,$encoding);
if($length > $pad) $result = mb_substr($str,0,$pad,$encoding);
else if($length == $pad) $result = $str;
else $result = $str.str_repeat($pad_str,$pad - $length);
return $result;
}
答案 6 :(得分:0)
我对此的贡献。
/**
* Multibyte String Pad
*
* Functionally, the equivalent of the standard str_pad function, but is capable of successfully padding multibyte strings.
*
* @param string $input The string to be padded.
* @param int $length The length of the resultant padded string.
* @param string $padding The string to use as padding. Defaults to space.
* @param int $padType The type of padding. Defaults to STR_PAD_RIGHT.
* @param string $encoding The encoding to use, defaults to UTF-8.
*
* @return string A padded multibyte string.
*/
function mb_str_pad($input, $length, $padding = ' ', $padType = STR_PAD_RIGHT, $encoding = 'UTF-8')
{
$result = $input;
if (($paddingRequired = $length - mb_strlen($input, $encoding)) > 0) {
switch ($padType) {
case STR_PAD_LEFT:
$result =
mb_substr(str_repeat($padding, $paddingRequired), 0, $paddingRequired, $encoding).
$input;
break;
case STR_PAD_RIGHT:
$result =
$input.
mb_substr(str_repeat($padding, $paddingRequired), 0, $paddingRequired, $encoding);
break;
case STR_PAD_BOTH:
$leftPaddingLength = floor($paddingRequired / 2);
$rightPaddingLength = $paddingRequired - $leftPaddingLength;
$result =
mb_substr(str_repeat($padding, $leftPaddingLength), 0, $leftPaddingLength, $encoding).
$input.
mb_substr(str_repeat($padding, $rightPaddingLength), 0, $rightPaddingLength, $encoding);
break;
}
}
return $result;
}
单元测试方法
/**
* @dataProvider provideDataForMbStrPad
*
* @param string $input
* @param int $length
* @param string $padding
* @param int $padType
* @param string $result
*/
public function testMbStrPad($input, $length, $padding, $padType, $result)
{
$this->assertEquals($result, Strings::mbStrPad($input, $length, $padding, $padType));
}
上述单元测试的数据提供者
public function provideDataForMbStrPad()
{
return [
['Nhiều byte string đệm', 0, ' ', STR_PAD_BOTH, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 0, ' ', STR_PAD_LEFT, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 0, ' ', STR_PAD_RIGHT, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 0, '充', STR_PAD_BOTH, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 0, '充', STR_PAD_LEFT, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 0, '充', STR_PAD_RIGHT, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 0, '煻充', STR_PAD_BOTH, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 20, ' ', STR_PAD_BOTH, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 20, ' ', STR_PAD_LEFT, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 20, ' ', STR_PAD_RIGHT, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 20, '充', STR_PAD_BOTH, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 20, '充', STR_PAD_LEFT, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 20, '充', STR_PAD_RIGHT, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 20, '煻充', STR_PAD_BOTH, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 21, ' ', STR_PAD_BOTH, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 21, ' ', STR_PAD_LEFT, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 21, ' ', STR_PAD_RIGHT, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 21, '充', STR_PAD_BOTH, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 21, '充', STR_PAD_LEFT, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 21, '充', STR_PAD_RIGHT, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 21, '煻充', STR_PAD_BOTH, 'Nhiều byte string đệm'],
['Nhiều byte string đệm', 22, ' ', STR_PAD_BOTH, 'Nhiều byte string đệm '],
['Nhiều byte string đệm', 22, ' ', STR_PAD_LEFT, ' Nhiều byte string đệm'],
['Nhiều byte string đệm', 22, ' ', STR_PAD_RIGHT, 'Nhiều byte string đệm '],
['Nhiều byte string đệm', 22, '充', STR_PAD_BOTH, 'Nhiều byte string đệm充'],
['Nhiều byte string đệm', 22, '充', STR_PAD_LEFT, '充Nhiều byte string đệm'],
['Nhiều byte string đệm', 22, '充', STR_PAD_RIGHT, 'Nhiều byte string đệm充'],
['Nhiều byte string đệm', 22, '煻充', STR_PAD_BOTH, 'Nhiều byte string đệm煻'],
['Nhiều byte string đệm', 23, ' ', STR_PAD_BOTH, ' Nhiều byte string đệm '],
['Nhiều byte string đệm', 23, ' ', STR_PAD_LEFT, ' Nhiều byte string đệm'],
['Nhiều byte string đệm', 23, ' ', STR_PAD_RIGHT, 'Nhiều byte string đệm '],
['Nhiều byte string đệm', 23, '充', STR_PAD_BOTH, '充Nhiều byte string đệm充'],
['Nhiều byte string đệm', 23, '充', STR_PAD_LEFT, '充充Nhiều byte string đệm'],
['Nhiều byte string đệm', 23, '充', STR_PAD_RIGHT, 'Nhiều byte string đệm充充'],
['Nhiều byte string đệm', 23, '煻充', STR_PAD_BOTH, '煻Nhiều byte string đệm煻'],
['Nhiều byte string đệm', 24, ' ', STR_PAD_BOTH, ' Nhiều byte string đệm '],
['Nhiều byte string đệm', 24, ' ', STR_PAD_LEFT, ' Nhiều byte string đệm'],
['Nhiều byte string đệm', 24, ' ', STR_PAD_RIGHT, 'Nhiều byte string đệm '],
['Nhiều byte string đệm', 24, '充', STR_PAD_BOTH, '充Nhiều byte string đệm充充'],
['Nhiều byte string đệm', 24, '充', STR_PAD_LEFT, '充充充Nhiều byte string đệm'],
['Nhiều byte string đệm', 24, '充', STR_PAD_RIGHT, 'Nhiều byte string đệm充充充'],
['Nhiều byte string đệm', 24, '煻充', STR_PAD_BOTH, '煻Nhiều byte string đệm煻充'],
['Nhiều byte string đệm', 25, '煻充', STR_PAD_BOTH, '煻充Nhiều byte string đệm煻充'],
['Nhiều byte string đệm', 26, '煻充', STR_PAD_BOTH, '煻充Nhiều byte string đệm煻充煻'],
];
}
答案 7 :(得分:0)
您也可以使用 str_repeat
。
function mb_str_pad($string, $length, $pad_string = " ")
{
return $string . str_repeat($pad_string, $length - mb_strlen($string));
}
您可以通过添加 STR_PAD_RIGHT
、STR_PAD_LEFT
或 STR_PAD_BOTH
来升级此功能;