Truncar uma corda multibyte para n chars
Pergunta
Estou tentando obter esse método em um filtro de string funcionando:
public function truncate($string, $chars = 50, $terminator = ' …');
Eu esperaria isso
$in = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYXZ1234567890";
$out = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV …";
e também isso
$in = "âãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝ";
$out = "âãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđ …";
Aquilo é $chars
menos os chars do $terminator
corda.
Além disso, o filtro deve cortar na primeira palavra limite abaixo do $chars
limite, por exemplo
$in = "Answer to the Ultimate Question of Life, the Universe, and Everything.";
$out = "Answer to the Ultimate Question of Life, the …";
Tenho certeza de que isso deve funcionar com essas etapas
- Substituir a quantidade de chars no Terminator da máxima chars
- Validar que a string é mais longa que o limite calculado ou devolva -a inalterada
- Encontre o último personagem do espaço na string abaixo do limite calculado para obter o limite do Word
- Corte a corda no último espaço ou limite calculado se nenhum último espaço for encontrado
- Anexar o Terminator à String
- Retornar string
No entanto, eu tentei várias combinações de str*
e mb_*
Funções agora, mas todos produziram resultados errados. Isso não pode ser tão difícil, então estou obviamente perdendo alguma coisa. Alguém compartilharia uma implementação funcional para isso ou Aponte -me para um recurso em que finalmente posso entender como fazê -lo.
Obrigado
Ps sim, eu verifiquei https://stackoverflow.com/search?q=truncate+string+php antes da :)
Solução
Experimente isso:
function truncate($string, $chars = 50, $terminator = ' …') {
$cutPos = $chars - mb_strlen($terminator);
$boundaryPos = mb_strrpos(mb_substr($string, 0, mb_strpos($string, ' ', $cutPos)), ' ');
return mb_substr($string, 0, $boundaryPos === false ? $cutPos : $boundaryPos) . $terminator;
}
Mas você precisa garantir que sua codificação interna esteja definida corretamente.
Outras dicas
Acabei de descobrir que o PHP já tem um truncado multibyte com
mb_strimwidth
- Obtenha string truncada com largura especificada
No entanto, não obedece aos limites das palavras. Mas é útil, no entanto!
Normalmente não gosto de codificar uma resposta inteira a uma pergunta como essa. Mas também acabei de acordar e pensei que talvez sua pergunta me ficasse de bom humor para o programa pelo resto do dia.
Eu não tentei executar isso, mas ele deveria funcionar ou pelo menos levar 90% do caminho para lá.
function truncate( $string, $chars = 50, $terminate = ' ...' )
{
$chars -= mb_strlen($terminate);
if ( $chars <= 0 )
return $terminate;
$string = mb_substr($string, 0, $chars);
$space = mb_strrpos($string, ' ');
if ($space < mb_strlen($string) / 2)
return $string . $terminate;
else
return mb_substr($string, 0, $space) . $terminate;
}