PHP中更智能的自动换行用于长词?

时间:2012-03-22 00:57:03

标签: php word-wrap line-breaks

我正在寻找一种方法让PHP中的自动换行更聪明一些。因此,它不会预先打破长字,只留下任何先前的小字在一行上。

让我说我有这个(真正的文字总是完全动态的,这只是为了展示):

wordwrap('hello! heeeeeeeeeeeeeeereisaverylongword', 25, '<br />', true);

输出:

  

您好!
  heeeeeeeeeeeeeeereisavery
  长字

看,它在第一行留下了单词。 如何让它输出更像这样的东西:

  

您好! heeeeeeeeeeee
  eeereisaverylongword

因此它利用每条线上的任何可用空间。我已经尝试了几个自定义函数,但没有一个是有效的(或者它们有一些缺点)。

5 个答案:

答案 0 :(得分:15)

我已经开始使用这个智能文字包装的自定义功能了:

function smart_wordwrap($string, $width = 75, $break = "\n") {
    // split on problem words over the line length
    $pattern = sprintf('/([^ ]{%d,})/', $width);
    $output = '';
    $words = preg_split($pattern, $string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

    foreach ($words as $word) {
        if (false !== strpos($word, ' ')) {
            // normal behaviour, rebuild the string
            $output .= $word;
        } else {
            // work out how many characters would be on the current line
            $wrapped = explode($break, wordwrap($output, $width, $break));
            $count = $width - (strlen(end($wrapped)) % $width);

            // fill the current line and add a break
            $output .= substr($word, 0, $count) . $break;

            // wrap any remaining characters from the problem word
            $output .= wordwrap(substr($word, $count), $width, $break, true);
        }
    }

    // wrap the final output
    return wordwrap($output, $width, $break);
}

$string = 'hello! too long here too long here too heeeeeeeeeeeeeereisaverylongword but these words are shorterrrrrrrrrrrrrrrrrrrr';
echo smart_wordwrap($string, 11) . "\n";

编辑:发现了几个警告。对此(以及本机功能)的一个主要警告是缺少多字节支持。

答案 1 :(得分:12)

怎么样

$string = "hello! heeeeeeeeeeeeeeereisaverylongword";
$break = 25;

echo implode(PHP_EOL, str_split($string, $break));

哪个输出

hello! heeeeeeeeeeeeeeere                                                                                                                                                           
isaverylongword

str_split()将字符串转换为$ break size chunk的数组。

implode()使用胶水将数组作为字符串连接在一起,在这种情况下,胶水是行尾标记(PHP_EOL),尽管它可以很容易地成为“<br/>

答案 2 :(得分:10)

这也是一个解决方案(对于浏览器等):

$string = 'hello! heeeeeeeeeeeeeeeeeeeeeereisaverylongword';
echo preg_replace('/([^\s]{20})(?=[^\s])/', '$1'.'<wbr>', $string);

它将<wbr>放在包含20个或更多字符的单词

<wbr>表示&#34;分词机会&#34;所以只有 才会中断(由元素/浏览器/查看器/其他的宽度决定)。否则它是看不见的。

适用于没有固定宽度的流畅/响应式布局。而且不像php的wordwrap那样包裹奇怪

答案 3 :(得分:5)

您可以使用CSS来完成此任务。

word-wrap: break-word;

这会打破你的话。这是一个链接,可以看到它的实际效果:

http://www.css3.info/preview/word-wrap/

答案 4 :(得分:2)

这应该可以解决问题......

$word = "hello!" . wordwrap('heeeeeeeeeeeeeeereisaverylongword', 25, '<br />', true);
echo $word;