I have two strings:
$a = '/srv/http/projects/name';
$b = '/projects/name/some/dir';
And I would like to get a merged string with not repeated common part:
$c = '/srv/http/projects/name/some/dir';
Is there any effective way to get it ?
I have two strings:
$a = '/srv/http/projects/name';
$b = '/projects/name/some/dir';
And I would like to get a merged string with not repeated common part:
$c = '/srv/http/projects/name/some/dir';
Is there any effective way to get it ?
It's kinda ugly, and assumes your strings always start with '/'... but:
$a = '/srv/http/projects/name';
$b = '/projects/name/some/dir';
$merged = array_merge(explode('/', $a), explode('/', $b) );
$unique = array_unique($merged);
$c = implode('/', $unique);
print $c; // prints "/srv/http/projects/name/some/dir"
function f($a, $b)
{
for($i=0; count($a) > $i ; $i++)
{
if(strpos($b, substr($a, $i)) !== FALSE)
return substr($a, 0, $i-1).$b;
}
return $a.$b;
}
Nothing that I know of out-of-the-box. but this should do it:
function merge_overlap($left, $right) {
// continue checking larger portions of $right
for($l = 1; $l < strlen($right); $l++) {
// if we no longer have a matching subsection return what's left appended
if(strpos($left, substr($right, 0, $l)) === false) {
return $left . substr($right, $l - 1);
}
}
// no overlap, return all
return $left . $right;
}
EDIT: Had an OBO, updated.
UPDATE: That was not the solution, strpos() is matching portions of text anywhere in the left path, should compare against tail.
Here is the correct implementation for my approach:
function merge_overlap($left, $right) {
$l = strlen($right);
// keep checking smaller portions of right
while($l > 0 && substr($left, $l * -1) != substr($right, 0, $l))
$l--;
return $left . substr($right, $l);
}
Try this:
function merge($a, $b) {
// divide into path parts to compare the parts
$start = preg_split('%/%', $a, -1, PREG_SPLIT_NO_EMPTY);
$end = preg_split('%/%', $b, -1, PREG_SPLIT_NO_EMPTY);
// if the first part of the first path is in the second path than switch
if(in_array($start[0], $end)) {
$temp = $start;
$start = $end;
$end = $temp;
}
$parts = array();
// get the index of the last part of the first path in the second path
$index = array_search($start[count($start)-1], $end);
// if the part exists, remove the first parts of the second path
if($index !== false) {
$parts = array_merge($start, array_slice($end, $index+1));
}
return '/' . join('/', $parts);
}
$a = '/srv/http/projects/name';
$b = '/projects/name/some/dir';
print merge($a, $b);
This gives me:
/srv/http/projects/name/some/dir
You might have to provide a default value or whatever if the path have no common part.
I don't think there's a "smart" way to do that. Just iterate over $a
until all of the rightmost tokens match the same number of tokens at the beginning of $b
.
Here I explode()
both strings so that I can easily capture the right number of tokens via array_slice()
.
$a = '/srv/http/projects/name/http';
$b = '/projects/name/http/some/dir';
var_dump(merge_path($a, $b));
function merge_path($path1, $path2)
{
$p1 = explode('/', trim($path1,' /'));
$p2 = explode('/', trim($path2,' /'));
$len = count($p1);
do
{
if (array_slice($p1, -$len) === array_slice($p2, 0, $len))
{
return '/'
. implode('/', array_slice($p1, 0, -$len))
. '/'
. implode('/', $p2);
}
}
while (--$len);
return false;
}