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

发布于 2022-09-01 15:21:44 字数 668 浏览 49 评论 0

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

比如

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

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

笨方法是:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

流心雨 2022-09-08 15:21:44

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

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

更新 解决 @AlanZhang 提的bug

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

http://3v4l.org/eB8Km

溺渁∝ 2022-09-08 15:21:44

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

for(var index=0;index<$a.length;index++){
    if($a.charAt(index)!=$b.charAt(index)){
       return $a.substring(index);
    }
}

坐等楼下好办法

混吃等死 2022-09-08 15:21:44
for($i=0;$i<strlen($a);$i++) {
    $currentPartA = substr($a,0,$i);  //截取相同长度的字符串
    $currentPartB = substr($b,0,$i);
    if($currentPartA == $currentPartB) {
        $prevWord = substr($a,$i-1,1);
        if($prevWord == '/') {        
            $leftA = substr($a,$i);    // 如果当前截取的字符串相同 并且前一个是‘/’,则获取一次
            continue;
        }
     } else {
         break;                        
     }
}
echo $leftA;
娇纵 2022-09-08 15:21:44

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

$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));
云之铃。 2022-09-08 15:21:44

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/

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

那小子欠揍 2022-09-08 15:21:44

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

熟练后比Ctrl+h快多了

枫林﹌晚霞¤ 2022-09-08 15:21:44
可以配合字符串查找位置函数替换掉
不过还是推荐使用shell处理
记忆之渊 2022-09-08 15:21:44

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

阿楠 2022-09-08 15:21:44

replace(str|rgExp,’‘) 替换字符串
这里的替换只能执行一次,不能够进行全局匹配,如果需要全局匹配,则应使用正则表达式

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文