Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split Strings in Half (Word-Aware) with PHP

Tags:

string

php

split

I'm trying to split strings in half, and it should not split in the middle of a word.

So far I came up with the following which is 99% working :

$text = "The Quick : Brown Fox Jumped Over The Lazy / Dog";
$half = (int)ceil(count($words = str_word_count($text, 1)) / 2); 
$string1 = implode(' ', array_slice($words, 0, $half));
$string2 = implode(' ', array_slice($words, $half));

This does work, correctly splitting any string in half according to the number of words in the string. However, it is removing any symbols in the string, for example for the above example it would output :

The Quick Brown Fox Jumped
Over The Lazy Dog

I need to keep all the symbols like : and / in the string after being split. I don't understand why the current code is removing the symbols... If you can provide an alternative method or fix this method to not remove symbols, it would be greatly appreciated :)

like image 741
Leo44 Avatar asked Nov 18 '11 18:11

Leo44


5 Answers

As usual, regex spares the developer a lot of tedious string manipulation calls and unnecessary script bloat. I'll even go out on a limb and say that the regex pattern might be easier to understand that the string function laden scripts.

Code: (Demo)

$text = "The Quick : Brown Fox Jumped Over The Lazy / Dog";
$halfWay = (int)(strlen($text) / 2);
var_export(
    preg_split(
        '~.{0,' . $halfWay . '}\K\s~s',
        $text,
        2
    )
);

Output:

array (
  0 => 'The Quick : Brown Fox',
  1 => 'Jumped Over The Lazy / Dog',
)

Effectively, we calculate the center of the string by counting its characters, then dividing by two and removing any decimal places.

Then greedily match zero to $halfWay number of characters, then forget those characters with \K, then split the string on the latest qualifying space. The 3rd parameter of preg_split() determines the maximum amount of elements which may be produced.

like image 152
mickmackusa Avatar answered Oct 19 '22 07:10

mickmackusa


Upon looking at your example output, I noticed all our examples are off, we're giving less to string1 if the middle of the string is inside a word rather then giving more.

For example the middle of The Quick : Brown Fox Jumped Over The Lazy / Dog is The Quick : Brown Fox Ju which is in the middle of a word, this first example gives string2 the split word; the bottom example gives string1 the split word.

Give less to string1 on split word

$text = "The Quick : Brown Fox Jumped Over The Lazy / Dog";

$middle = strrpos(substr($text, 0, floor(strlen($text) / 2)), ' ') + 1;

$string1 = substr($text, 0, $middle);  // "The Quick : Brown Fox "
$string2 = substr($text, $middle);  // "Jumped Over The Lazy / Dog"

Give more to string1 on split word

$text = "The Quick : Brown Fox Jumped Over The Lazy / Dog";

$splitstring1 = substr($text, 0, floor(strlen($text) / 2));
$splitstring2 = substr($text, floor(strlen($text) / 2));

if (substr($splitstring1, 0, -1) != ' ' AND substr($splitstring2, 0, 1) != ' ')
{
    $middle = strlen($splitstring1) + strpos($splitstring2, ' ') + 1;
}
else
{
    $middle = strrpos(substr($text, 0, floor(strlen($text) / 2)), ' ') + 1;    
}

$string1 = substr($text, 0, $middle);  // "The Quick : Brown Fox Jumped "
$string2 = substr($text, $middle);  // "Over The Lazy / Dog"
like image 43
Jeff Wilbert Avatar answered Oct 19 '22 08:10

Jeff Wilbert


function split_half($string, $center = 0.4) {
        $length2 = strlen($string) * $center;
        $tmp = explode(' ', $string);
        $index = 0; 
        $result = Array('', '');
        foreach($tmp as $word) {
            if(!$index && strlen($result[0]) > $length2) $index++;
            $result[$index] .= $word.' ';
        }
        return $result;
}

Demo: http://codepad.viper-7.com/I58gcI

like image 8
Peter Avatar answered Oct 19 '22 07:10

Peter


I know this is an old question, but I have the following piece of code that should do what is needed.

It by default it splits the string on the first occurrence of a space after the middle. If there are no spaces after the middle, it looks for the last space before the middle.

function trim_text($input) {
    $middle = ceil(strlen($input) / 2);
    $middle_space = strpos($input, " ", $middle - 1);

    if ($middle_space === false) {
        //there is no space later in the string, so get the last sapce before the middle
        $first_half = substr($input, 0, $middle);
        $middle_space = strpos($first_half, " ");
    }

    if ($middle_space === false) {
        //the whole string is one long word, split the text exactly in the middle
        $first_half = substr($input, 0, $middle);
        $second_half = substr($input, $middle);
    }
    else {
        $first_half = substr($input, 0, $middle_space);
        $second_half = substr($input, $middle_space);
    }
        return array(trim($first_half), trim($second_half));
}

These are examples:

Example 1:

"WWWWWWWWWW WWWWWWWWWW WWWWWWWWWW WWWWWWWWWW"

Is split as

"WWWWWWWWWW WWWWWWWWWW"

"WWWWWWWWWW WWWWWWWWWW"

Example 2:

"WWWWWWWWWWWWWWWWWWWW WWWWWWWWWW WWWWWWWWWW"

Is split as

"WWWWWWWWWWWWWWWWWWWW"

"WWWWWWWWWW WWWWWWWWWW"

Example 3:

"WWWWWWWWWW WWWWWWWWWW WWWWWWWWWWWWWWWWWWWW"

Is split as

"WWWWWWWWWW WWWWWWWWWW"

"WWWWWWWWWWWWWWWWWWWW"

Example 4:

"WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW"

Is split as

"WWWWWWWWWWWWWWWWWWWW"

"WWWWWWWWWWWWWWWWWWWW"

Hope this can help someone out there :)

like image 2
Rickus Harmse Avatar answered Oct 19 '22 08:10

Rickus Harmse


function split_half($string){
$result= array();
$text = explode(' ', $string);
$count = count($text);
$string1 = '';
$string2 = '';
if($count > 1){
    if($count % 2 == 0){
        $start = $count/2;
        $end = $count;
        for($i=0; $i<$start;$i++){
            $string1 .= $text[$i]." ";
        }
        for($j=$start; $j<$end;$j++){
            $string2 .= $text[$j]." ";
        }           
    $result[] = $string1;
    $result[] = $string2;
    }
    else{
        $start = round($count/2)-1;
        $end = $count;
        for($i=0; $i<$start;$i++){
            $string1 .= $text[$i]." ";
        }
        for($j=$start; $j<$end;$j++){
            $string2 .= $text[$j]." ";
        }           
    $result[] = $string1;
    $result[] = $string2;

    }
}
else{
    $result[] = $string;
}
return $result;
}

Use this function to split string into half words..

like image 1
Divyesh Prajapati Avatar answered Oct 19 '22 09:10

Divyesh Prajapati