开发者

Efficient way to get last part of string only after a certain base string

开发者 https://www.devze.com 2023-02-17 06:36 出处:网络
What is an efficient way to get the part of a string after the occurrence of a certain needle, only if that needle is at the start of the haystack. Similar to strstr(), but excluding the needle, and o

What is an efficient way to get the part of a string after the occurrence of a certain needle, only if that needle is at the start of the haystack. Similar to strstr(), but excluding the needle, and only when found at the beginning of the string.

If it isn't found, it should preferably return false.

I have the feeling I'm overlooking some very obvious PHP functions here, but I can't seem to think of them right now.

For example:

$basePath = '/some/dir/';

$result = some_function( '/some/dir/this/is/the/relative/part', $basePath );
/*
should return:
this/is/the/relative/part
*/

$result = some_function( '/fake/dir/this/is/the/relative/part', $basePath );
$result = some_function( '/pre/some/dir/this/is/the/relative/part', $basePath );
/*
last example has '/some/dir/' in it, but not at start.
should both preferably return:
false
*/

I'll be using this for a filesystem service that should act as a sandbox, and should be able to give out and take in paths, rela开发者_StackOverflow社区tive to the base sand box directory.


This case calls for strncmp:

function some_function($path, $base) {
    if (strncmp($path, $base, $n = strlen($base)) == 0) {
        return substr($path, $n);
    }
}


Put more simply than the other examples:

function some_function($path,$base){
  $baselen = strlen($base);
  if (strpos($path,$base) === 0 && strlen($path)>$baselen)
    return substr($path,$baselen);
  return false;
}

DEMO

Alternate using strncmp, too: DEMO


function some_function($haystack, $baseNeedle) {
   if (! preg_match('/^' . preg_quote($baseNeedle, '/') . '(.*)$/', $haystack, $matches)) {
      return false;
   }
   return $matches[1];
}


function some_function($path, $basePath) {
    $pos = strpos($path, $basePath);
    if ($pos !== false) {
        return substr($path, strlen($basePath));
    } else {
        return false;
    }
}

But what about this?

some_function('/base/path/../../secret/password.txt', '/base/path/safe/dir/');

You likely want to call realpath() on $path first, so that it is fully simplified, before using some_function().


Not sure if there's a built-in function for this.

function some_function($str1, $str2) {
  $l = strlen($str2);
  if (substr($str1, 0, $l) == $str2)
    return substr($str1, $l);
  else
    return false;
}

For long $str1 and short $str2, I think this is going to be faster than using strpos.

If you're using this for paths, you might want to do some checking if the slashes are at the right place.


How about regular expressions?

$regexp = preg_quote($basepath, '/');
return preg_replace("/^$regexp/", "", $path);
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号