2

I'm looking to strip a string, $left from the left of another string, $right. Given:

$left  = 'alpha beta gamma';
$right = 'beta gamma delta';

The desired output would be:

string(6) " delta"

Now, I've sort of accomplished this. I've written a function, to achieve this exactly:

function strip_left_from_right($left, $right){
    for($i = 0, $m = strlen($left); $i <= $m; $i++){
        $needle = substr($left, -$i);
        if(substr($right, 0, strlen($needle)) == $needle){
            return substr($right, strlen($needle));
        }
    }
}

And it works fine. However I want it to be be "greedy", using as much of the $left string as possible. For instance:

$left  = "foofoofoofoo";
$right = "foofoofoobar";

// desired output
string(3) "bar"

// actual output
string(9) "foofoobar"

Essentially my question is two-fold;

  1. What would be the best way to perform a "greedy" match? (given I continue with this code)

And probably more important;

  2. Is there a better (non-iterative, set of core functions used in tandem) way to accomplish this?


The solution I went with, thanks to @Yoshi for getting my brain in that direction:

function intersect_split($left, $right, $greedy = true){
    for($i = 0, $m = strlen($left); $i <= $m; $i++){
        $chunk = substr($left, $i * (int) ($greedy ?: -1));
        if(substr($right, 0, strlen($chunk)) == $chunk){
            return array(
                (string) substr($left, 0, $m - strlen($chunk)),
                (string) substr($right, strlen($chunk)),
            );
        }
    }
    return array($left, $right);
}

$left  = 'foo bar bar bar bar';
$right = 'bar bar bar bar baz';

var_dump( intersect_split($left, $right, true) );
var_dump( intersect_split($left, $right, false) );

Produces:

array(2) {
  [0]=>
  string(4) "foo "
  [1]=>
  string(4) " baz"
}
array(2) {
  [0]=>
  string(16) "foo bar bar bar "
  [1]=>
  string(16) " bar bar bar baz"
}

So now I essentially split the string at an intersecting match of the right of the $left argument and left of the $right argument, producing the leading and trailing strings in an array. $greedy produces the obvious difference in results.

Dan Lugg
  • 20,192
  • 19
  • 110
  • 174
  • What's the purpose of doing that? –  Jul 15 '11 at 08:31
  • @Pezhvak - General purpose string manipulation. Several instances where this is useful in an application I'm working on. – Dan Lugg Jul 15 '11 at 08:41
  • 1
    It looks similar to a diff system, you may be interested in a diff implementation there https://github.com/paulgb/simplediff/blob/5bfe1d2a8f967c7901ace50f04ac2d9308ed3169/simplediff.php – Boris Guéry Jul 15 '11 at 08:43

1 Answers1

2

Not optimal, but at least it does the job:

function helper($left, $right) {
    $match = '';

    for ($i = strlen($left) - 1; $i >= 0; $i -= 1) {
        $chunk = substr($left, $i);
        $len = strlen($chunk);
        if (substr($right, 0, $len) == $chunk && $len > strlen($match)) {
            $match = $chunk;
        }
    }

    return substr($right, strlen($match));
}

echo helper('alpha beta gamma', 'beta gamma delta'); // output " delta"
echo helper('foofoofoofoo', 'foofoofoobar'); // output "bar"
Yoshi
  • 54,081
  • 14
  • 89
  • 103
  • Thanks @Yoshi - Your answer got me thinking in the direction I needed for sure; see question for solution, I'll mark yours accepted since it got me there :) – Dan Lugg Jul 15 '11 at 17:43