Smarter word-wrap in PHP for long words?

前端 未结 5 1467
無奈伤痛
無奈伤痛 2020-12-05 18:53

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.

Let\'s say I have

相关标签:
5条回答
  • 2020-12-05 19:32

    You can use CSS to accomplish this.

    word-wrap: break-word;
    

    That will break the word for you. Here is a link to see it in action:

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

    0 讨论(0)
  • 2020-12-05 19:33

    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.

    0 讨论(0)
  • 2020-12-05 19:36

    This is also a solution (for browsers etc.):

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

    It puts a <wbr> at words with 20 or more characters

    <wbr> means "word break opportunity" so it only breaks if it has to (dictated by width of element/browser/viewer/other). It's invisible otherwise.

    Good for fluid/responsive layout where there is no fixed width. And does not wrap odd like php's wordwrap

    0 讨论(0)
  • 2020-12-05 19:41

    This should do the trick...

    $word = "hello!" . wordwrap('heeeeeeeeeeeeeeereisaverylongword', 25, '<br />', true);
    echo $word;
    
    0 讨论(0)
  • 2020-12-05 19:44

    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.

    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/>'

    0 讨论(0)
提交回复
热议问题