PHP пересечения строк, жадно обрезать слева направо - PullRequest
2 голосов
/ 15 июля 2011

Я хочу снять строку, $left слева от другой строки, $right. Дано:

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

Желаемый результат будет:

string(6) " delta"

Теперь, я вроде как достиг этого. Я написал функцию, чтобы достичь этого точно:

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));
        }
    }
}

И это прекрасно работает. Однако я хочу, чтобы он был " жадный ", используя как можно большую часть строки $left. Например:

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

// desired output
string(3) "bar"

// actual output
string(9) "foofoobar"

По сути, мой вопрос двоякий;

1. Как лучше всего провести матч " жадный "? ( учитывая, что я продолжаю с этим кодом )

И, наверное, важнее;

2. Есть ли лучший ( не итеративный набор основных функций, используемых в тандеме ), способ сделать это?


Решение, с которым я согласился, благодаря @Yoshi, который направил мой мозг в этом направлении:

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

Выдает:

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

Итак, теперь я по существу разделил строку в пересекающемся совпадении справа от аргумента $left и слева от аргумента $right, создавая начальную и конечную строки в массиве. $greedy дает очевидную разницу в результатах.

1 Ответ

2 голосов
/ 15 июля 2011

Не оптимально, но, по крайней мере, это делает работу:

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