Эффективный способ получить последнюю часть строки только после определенной базовой строки - PullRequest
0 голосов
/ 17 марта 2011

Какой эффективный способ получить часть нити после появления определенной иглы, только , если эта игла находится в начале стога сена. Аналогично strstr(), но исключая иглу и только в том случае, если найдено в начале строки.

Если он не найден, предпочтительно вернуть false.

У меня такое ощущение, что я упускаю некоторые очень очевидные функции PHP здесь, но я не могу думать о них прямо сейчас.

Например:

$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
*/

Я буду использовать это для службы файловой системы, которая должна выступать в качестве изолированной программной среды и должна иметь возможность выдавать и извлекать пути относительно базового каталога программной среды.

Ответы [ 6 ]

3 голосов
/ 17 марта 2011

В этом случае требуется strncmp :

function some_function($path, $base) {
    if (strncmp($path, $base, $n = strlen($base)) == 0) {
        return substr($path, $n);
    }
}
1 голос
/ 17 марта 2011
function some_function($haystack, $baseNeedle) {
   if (! preg_match('/^' . preg_quote($baseNeedle, '/') . '(.*)$/', $haystack, $matches)) {
      return false;
   }
   return $matches[1];
}
1 голос
/ 17 марта 2011

Проще говоря, чем другие примеры:

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

DEMO

Альтернативное использование strncmp тоже: DEMO

0 голосов
/ 17 марта 2011

Как насчет регулярных выражений?

$regexp = preg_quote($basepath, '/');
return preg_replace("/^$regexp/", "", $path);
0 голосов
/ 17 марта 2011

Не уверен, что для этого есть встроенная функция.

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

Для длинных $str1 и коротких $str2, я думаю, это будет быстрее, чем при использовании strpos.

Если вы используете это для путей, вам может потребоваться проверить, находятся ли косые черты в правильном месте.

0 голосов
/ 17 марта 2011
function some_function($path, $basePath) {
    $pos = strpos($path, $basePath);
    if ($pos !== false) {
        return substr($path, strlen($basePath));
    } else {
        return false;
    }
}

А как насчет этого?

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

Вы, вероятно, хотите сначала позвонить realpath() на $path, чтобы он полностью упростился перед использованием some_function().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...