25

I'm looking for something along the line of

str_split_whole_word($longString, $x)

Where $longString is a collection of sentences, and $x is the character length for each line. It can be fairly long, and I want to basically split it into multiple lines in the form of an array.

For example:

$longString = 'I like apple. You like oranges. We like fruit. I like meat, also.';
$lines = str_split_whole_word($longString, $x);

Desired output:

$lines = Array(
    [0] = 'I like apple. You'
    [1] = 'like oranges. We'
    [2] = and so on...
)
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
laketuna
  • 3,832
  • 14
  • 59
  • 104

4 Answers4

62

The easiest solution is to use wordwrap(), and explode() on the new line, like so:

$array = explode( "\n", wordwrap( $str, $x));

Where $x is a number of characters to wrap the string on.

nickb
  • 59,313
  • 13
  • 108
  • 143
19

This code avoid breaking words, you won't get it using wordwrap().

The maximum length is defined using $maxLineLength. I've done some tests and it works fine.

$longString = 'I like apple. You like oranges. We like fruit. I like meat, also.';

$words = explode(' ', $longString);

$maxLineLength = 18;

$currentLength = 0;
$index = 0;

foreach ($words as $word) {
    // +1 because the word will receive back the space in the end that it loses in explode()
    $wordLength = strlen($word) + 1;

    if (($currentLength + $wordLength) <= $maxLineLength) {
        $output[$index] .= $word . ' ';
        $currentLength += $wordLength;
    } else {
        $index += 1;
        $currentLength = $wordLength;
        $output[$index] = $word;
    }
}
Marcio Mazzucato
  • 8,841
  • 9
  • 64
  • 79
14

Use wordwrap() to insert the linebreaks, then explode() on those linebreaks:

// Wrap at 15 characters
$x = 15;
$longString = 'I like apple. You like oranges. We like fruit. I like meat, also.';
$lines = explode("\n", wordwrap($longString, $x));

var_dump($lines);
array(6) {
  [0]=>
  string(13) "I like apple."
  [1]=>
  string(8) "You like"
  [2]=>
  string(11) "oranges. We"
  [3]=>
  string(13) "like fruit. I"
  [4]=>
  string(10) "like meat,"
  [5]=>
  string(5) "also."
}
Michael Berkowski
  • 267,341
  • 46
  • 444
  • 390
3

This whole task can be accomplished with just one preg_ function call instead of indirectly injecting a bunch of newlines and then splitting on those.

  1. Match any character between zero and $maxLength times.
  2. Forget/Release the matched characters from #1 with \K.
  3. Match the next one or more whitespace characters or the end of the string. The characters/position matched here will be consumed in the splitting process and will not appear in the output array.
  4. Set the preg_ function to exclude the empty element that is produced by splitting on the end of string position with PREG_SPLIT_NO_EMPTY.

Code: (Demo)

$longString = 'I like apple. You like oranges. We like fruit. I like meat, also.';
$maxLength = 18;

var_export(
    preg_split("/.{0,{$maxLength}}\K(?:\s+|$)/", $longString, 0, PREG_SPLIT_NO_EMPTY)
);

Output:

array (
  0 => 'I like apple. You',
  1 => 'like oranges. We',
  2 => 'like fruit. I like',
  3 => 'meat, also.',
)

If your input string might contain newlines, then just add the s pattern modifier.
/.{0,{$maxLength}}\K(?:\s+|$)/s (Demo)

mickmackusa
  • 43,625
  • 12
  • 83
  • 136