当前位置:Gxlcms > PHP教程 > 求一个更聪明的方法:将字符串A开头与字符串B开头相同的部分去掉。

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

时间:2021-07-01 10:21:17 帮助过:15人阅读

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

比如

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

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

笨方法是:

  1. <code>$a = '/www/proj-asd/app/home/news';
  2. $b = '/www/proj-asd/app/_view';
  3. echo getRelPath($a, $b); // home/news
  4. function getRelPath($a, $b)
  5. {
  6. $a = strtr($a, '\\', '/');
  7. $b = strtr($b, '\\', '/');
  8. $a = explode('/', $a);
  9. $b = explode('/', $b);
  10. foreach ($a as $i=>$av) {
  11. $bv = $b[$i];
  12. if ($av===$bv) {
  13. unset($a[$i]);
  14. }else{
  15. break;
  16. }
  17. }
  18. return implode('/', $a);
  19. }
  20. </code>

回复内容:

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

比如

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

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

笨方法是:

  1. <code>$a = '/www/proj-asd/app/home/news';
  2. $b = '/www/proj-asd/app/_view';
  3. echo getRelPath($a, $b); // home/news
  4. function getRelPath($a, $b)
  5. {
  6. $a = strtr($a, '\\', '/');
  7. $b = strtr($b, '\\', '/');
  8. $a = explode('/', $a);
  9. $b = explode('/', $b);
  10. foreach ($a as $i=>$av) {
  11. $bv = $b[$i];
  12. if ($av===$bv) {
  13. unset($a[$i]);
  14. }else{
  15. break;
  16. }
  17. }
  18. return implode('/', $a);
  19. }
  20. </code>

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

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

更新 解决 @AlanZhang 提的bug

  1. <code>php</code><code><!--?php
  2. $a = '/www/proj-asd/app/home/news';
  3. $b = '/www/proj-asd/app/_view/news';
  4. echo getRelPath($a, $b); // home/news
  5. function getRelPath($a, $b) {
  6. $a = explode('/', $a);
  7. $b = explode('/', $b);
  8. $diff = array_diff_assoc($a, $b);
  9. return implode('/', array_slice($a, key($diff)));
  10. }
  11. </code--></code>

http://3v4l.org/eB8Km

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

  1. <code>for(var index=0;index<$a.length;index++){
  2. if($a.charAt(index)!=$b.charAt(index)){
  3. return $a.substring(index);
  4. }
  5. }
  6. </code>

坐等楼下好办法

  1. <code>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;="" <="" code=""></strlen($a);$i++)></code>

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

  1. <code>$a = '/www/proj-asd/app/home/news';
  2. $b = '/www/proj-asd/app/_view';
  3. function getRelPath($a, $b){
  4. if($a[0] != $b[0]) return $a;
  5. return getRelPath(substr($a, 1), substr($b, 1));
  6. }
  7. var_dump(getRelPath($a, $b));
  8. </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快多了

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

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

人气教程排行