PHP 中更智能的长字自动换行?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9815040/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Smarter word-wrap in PHP for long words?
提问by mowgli
I'm looking for a way to make word-wrap in PHP a bit smarter. So it doesn't pre-break long words leaving any prior small words alone on one line.
我正在寻找一种使 PHP 中的自动换行更智能的方法。所以它不会预先打破长词,将任何先前的小词单独留在一行上。
Let's say I have this (the real text is always completely dynamic, this is just to show):
假设我有这个(真实的文本总是完全动态的,这只是为了显示):
wordwrap('hello! heeeeeeeeeeeeeeereisaverylongword', 25, '<br />', true);
This outputs:
这输出:
hello!
heeeeeeeeeeeeeeereisavery
longword
你好!
heeeeeeeeeeeeeeeeereisavery
longword
See, it leaves the small word alone on the first line. How can I get it to ouput something more like this:
看,它把小词单独留在第一行。我怎样才能让它输出更像这样的东西:
hello! heeeeeeeeeeee
eeereisaverylongword
你好!heeeeeeeeeeee
eeereisaverylongword
So it utilizes any available space on each line. I have tried several custom functions, but none have been effective (or they had some drawbacks).
所以它利用每一行上的任何可用空间。我尝试了几个自定义函数,但没有一个有效(或者它们有一些缺点)。
采纳答案by cmbuckley
I've had a go at the custom function for this smart wordwrap:
我已经尝试了这个智能自动换行的自定义函数:
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";
EDIT: Spotted a couple of caveats. One major caveat with this (and also with the native function) is the lack of multibyte support.
编辑:发现了几个警告。对此(以及本机函数)的一个主要警告是缺乏多字节支持。
回答by frglps
How about
怎么样
$string = "hello! heeeeeeeeeeeeeeereisaverylongword";
$break = 25;
echo implode(PHP_EOL, str_split($string, $break));
Which outputs
哪些输出
hello! heeeeeeeeeeeeeeere
isaverylongword
str_split() converts the string to an array of $break size chunks.
str_split() 将字符串转换为 $break 大小块的数组。
implode() joins the array back together as a string using the glue which in this case is an end of line marker (PHP_EOL) although it could as easily be a '<br/>
'
implode() 使用胶水将数组重新连接为一个字符串,在这种情况下它是行尾标记(PHP_EOL),尽管它很容易是一个 ' <br/>
'
回答by mowgli
This is also a solution (for browsers etc.):
这也是一个解决方案(对于浏览器等):
$string = 'hello! heeeeeeeeeeeeeeeeeeeeeereisaverylongword';
echo preg_replace('/([^\s]{20})(?=[^\s])/', ''.'<wbr>', $string);
It puts a <wbr>
at words with 20 or more characters
它<wbr>
在单词中放置20 个或更多字符
<wbr>
means "word break opportunity" so it onlybreaks if it has to (dictated by width of element/browser/viewer/other). It's invisible otherwise.
<wbr>
表示“断字机会”,因此只有在必须时才会中断(由元素/浏览器/查看器/其他的宽度决定)。否则是看不见的。
Good for fluid/responsive layout where there is no fixed width. And does not wrap odd like php's wordwrap
适用于没有固定宽度的流体/响应式布局。并且不会像 php 的 wordwrap 那样奇怪
回答by brenjt
You can use CSS to accomplish this.
您可以使用 CSS 来完成此操作。
word-wrap: break-word;
That will break the word for you. Here is a link to see it in action:
那会为你打破这个词。这是一个链接,可以查看它的实际效果:
回答by Paul Dessert
This should do the trick...
这应该可以解决问题...
$word = "hello!" . wordwrap('heeeeeeeeeeeeeeereisaverylongword', 25, '<br />', true);
echo $word;