Home  >  Article  >  Backend Development  >  求一个更聪明的方法:将字符串A开头与字符串B开头相同的部分去掉。

求一个更聪明的方法:将字符串A开头与字符串B开头相同的部分去掉。

WBOY
WBOYOriginal
2016-06-06 20:31:421270browse

将字符串A开头 与字符串B开头 相同的部分去掉。

比如

<code>$a = '/www/proj-asd/app/home/news';
$b = '/www/proj-asd/app/_view';
</code>

那么需要提取出来的部分就是 home/news

笨方法是:

<code>$a = '/www/proj-asd/app/home/news';
$b = '/www/proj-asd/app/_view';

echo getRelPath($a, $b); // home/news

function getRelPath($a, $b)
{
    $a = strtr($a, '\\', '/');
    $b = strtr($b, '\\', '/');

    $a = explode('/', $a);
    $b = explode('/', $b);

    foreach ($a as $i=>$av) {
        $bv = $b[$i];
        if ($av===$bv) {
            unset($a[$i]);
        }else{
            break;
        }
    }

    return implode('/', $a);
}
</code>

回复内容:

将字符串A开头 与字符串B开头 相同的部分去掉。

比如

<code>$a = '/www/proj-asd/app/home/news';
$b = '/www/proj-asd/app/_view';
</code>

那么需要提取出来的部分就是 home/news

笨方法是:

<code>$a = '/www/proj-asd/app/home/news';
$b = '/www/proj-asd/app/_view';

echo getRelPath($a, $b); // home/news

function getRelPath($a, $b)
{
    $a = strtr($a, '\\', '/');
    $b = strtr($b, '\\', '/');

    $a = explode('/', $a);
    $b = explode('/', $b);

    foreach ($a as $i=>$av) {
        $bv = $b[$i];
        if ($av===$bv) {
            unset($a[$i]);
        }else{
            break;
        }
    }

    return implode('/', $a);
}
</code>

先把题目理解成路径匹配(而非纯字符串)

那么array_diff_assoc可能是题主想要的方法

更新 解决 @AlanZhang 提的bug

<code>php</code><code><?php $a = '/www/proj-asd/app/home/news';
$b = '/www/proj-asd/app/_view/news';

echo getRelPath($a, $b); // home/news


function getRelPath($a, $b) {
    $a = explode('/', $a);
    $b = explode('/', $b);
    $diff = array_diff_assoc($a, $b);

    return implode('/', array_slice($a, key($diff)));
}
</code></code>

http://3v4l.org/eB8Km

要求全字符匹配只能想到每个字符都去匹配

<code>for(var index=0;index</code>

坐等楼下好办法

<code>for($i=0;$i<strlen substr if continue else break echo></strlen></code>

用回调不是更快?如果确定是地址的话,先转数组再用回调,思路大同小异,就不写了。

<code>$a = '/www/proj-asd/app/home/news';
$b = '/www/proj-asd/app/_view';

function getRelPath($a, $b){
    if($a[0] != $b[0]) return $a;
    return getRelPath(substr($a, 1), substr($b, 1));

}
var_dump(getRelPath($a, $b));
</code>

jsven的方法和楼主的一样。
邹世杰的方法其实也和楼主一样,不过是递归版。

我这里说一个思路,取a b的长度最小值。
然后做二分法。

$a = '/www/proj-asd/app/home/news';
$b = '/www/proj-asd/app/_view';

截半,/www/proj-a 相同。

剩下'sd/app/_view',再截半,
是sd/app/,相同。此时相同的部分为/www/proj-asd/app/

剩下是'home/' 和'view' 比较。
截半,ho和_v,不同。
再截半,h和
,不同。

所以相同部分为/www/proj-asd/app/

只不过代码写起来,肯定没有直接挨个字符对比的省事。

如果是为了编辑一个文件列表,比如SVN的log中的文件列表去掉版本库目录,可以直接用列编辑:
gg - 移到开头
Ctrl+v - 开始列模式
w或l - 向右移动光标到所需要的位置
...
x - 删除公共前缀

熟练后比Ctrl+h快多了

<code>可以配合字符串查找位置函数替换掉
不过还是推荐使用shell处理
</code>

直接写个正则替换为空的不就行了这么费事。。。。

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn