2012-03-22 216 views
14

我正在寻找一种让PHP中的word-wrap更智能一点的方法。因此,它不会预先打破长单词,而只在一行中留下任何先前的小单词。更长的单词在PHP中更智能的单词换行?

比方说,我有这样的(真正的文本始终是完全动态的,这只是说明):

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

此输出:

你好!
heeeeeeeeeeeeeeereisavery
长字

见,它留下孤独的小词的第一行。 我怎样才能让它输出更像这样的东西:

你好! heeeeeeeeeeee
eeereisaverylongword

所以它采用每行的任何可用空间。我尝试了几个自定义函数,但没有一个是有效的(或者他们有一些缺点)。

+0

我刚刚从Google来到这里。我很惊讶,这不起作用。这是PHP内置函数的错误吗?在我看来,当你将最后一个参数设置为true时,它应该使用所有可用的空间。为什么不这样做? – 2016-10-19 18:47:24

+0

@安德鲁是啊,我不知道。你可以使用CSS wrap方法,或者这个http://stackoverflow.com/questions/9815040/smarter-word-wrap-in-php-for-long-words/25273135#25273135(如果是网页浏览等)。和平 – mowgli 2016-10-19 23:28:01

回答

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"; 

编辑:发现了一个警告夫妇。与此(也与本机功能)一个主要的警告是缺乏多字节支持。

+0

什么$宽= 75设置excactly? – mowgli 2012-03-22 01:54:33

+0

函数签名与wordwrap(没有break参数)完全相同,因此它设置了75个字符的默认包装宽度。 – cmbuckley 2012-03-22 01:56:48

+0

没什么,只是他使用的默认值。如果你不用'11'提供你自己的,那么将使用'75'。 – Eli 2012-03-22 01:58:24

2

这应该做的伎俩......

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

我刚刚使用了一些例子的话。在实际使用中,文本将是完全动态的,所以我不能使用这个 – mowgli 2012-03-22 01:01:23

+0

不确定你是如何尝试这样做的,但为什么你不能动态地改变它?只需使用变量来设置文本 – 2012-03-22 01:04:53

+0

动态地改变什么?文本可以是任何东西,任何长度,任何数量的单词。我不知道第一个单词或任何单词会是什么;) – mowgli 2012-03-22 01:08:06

5

您可以使用CSS来实现这一目标。

word-wrap: break-word; 

这会打破你的话。这里是一个链接,看到它在行动:

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

+3

我不打破浏览器的话 – mowgli 2012-03-22 01:03:00

+0

这不适合我。我在桌子的td上试了一下。我在style和'word-wrap:break-word下应用了一些'width';' – 2012-07-03 11:30:35

+0

2014年,它在每个浏览器中都不起作用。有时php会覆盖你的屁股。 – Maelish 2014-08-07 16:43:44

11

如何

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

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

,输出

hello! heeeeeeeeeeeeeeere                                       
isaverylongword 

str_split()的字符串转换为$数组把大小块。

破灭(),使用胶水在这种情况下是线标记(PHP_EOL)的端部虽然也可以简单地是一个“<br/>

+0

这个词包装去哪里呢? ;) – mowgli 2012-03-22 01:25:21

+0

@frglps你是天才。感谢您的回答... – 2014-01-20 14:32:48

+0

即使是2017年,这也非常有帮助!谢谢:) – LecheDeCrema 2017-02-12 09:46:43

9

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

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

它把一个<wbr>在具有20个或更多字符

<wbr>手段“字破机会”,因此它场所是否具有(通过元件/浏览器的宽度决定/字浏览器/其他)。否则它是不可见的。

适用于没有固定宽度的流体/响应布局。并且不会像php的wordwrap那样包装奇怪