【问题标题】:Efficient way to get last part of string only after a certain base string仅在某个基本字符串之后获取字符串最后一部分的有效方法
【发布时间】:2011-03-17 16:34:20
【问题描述】:

在某个针出现后获取字符串部分的有效方法是什么,如果该针位于大海捞针的起点。类似于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
*/

我将把它用于应该充当沙盒的文件系统服务,并且应该能够提供和接收相对于基本沙盒目录的路径。

【问题讨论】:

    标签: php substring


    【解决方案1】:

    本案要求strncmp

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

    【讨论】:

    • 是的,我认为这是要走的路。谢谢。 Brad 早一点使用了一个非常相似的strncmp 变体。但这一个虽然有点时尚。 :D
    【解决方案2】:

    比其他例子更简单:

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

    DEMO

    也可以使用strncmpDEMO

    【讨论】:

    • 我非常喜欢strncmp 变体!
    • PS.:strncmp 变体上的 strlen($path) > $baselen 是多余的,不是吗?还是我在这里忽略了一些重要的东西?
    • @fireeyedboy:我添加了检查,以防路径与基础匹配。你会收到false 回复,基本上是“我没有更多信息可以获取”。
    • 啊,当然,聪明!虽然,在这种情况下,我不介意它返回一个空字符串。因为这将是一个有效的相对路径。不过好想。比我今天明亮得多。 :)
    • 关于您的strncasecomp() 评论。好点子!但是看到我今天很密集,我得先思考一下这件事的含义,然后再发表评论。 :) 到目前为止谢谢!
    【解决方案3】:
    function some_function($haystack, $baseNeedle) {
       if (! preg_match('/^' . preg_quote($baseNeedle, '/') . '(.*)$/', $haystack, $matches)) {
          return false;
       }
       return $matches[1];
    }
    

    【讨论】:

      【解决方案4】:
      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/');
      

      在使用some_function() 之前,您可能想先在$path 上调用realpath(),以便完全简化。

      【讨论】:

      • 关于realpath() 的好点,但我实际上已经在使用它了。谢谢!
      • @fireeyedboy:虽然它在 *nix 环境中确实有效。 ;-)(除非你切换到strncasecmp
      • @Brad:不确定我是否关注你。对不起,我今天有点紧张。你的意思是说realpath() 只在*nix 上有效?可能是因为区分大小写?
      • @fireeyedboy:实际上,我是一个滑倒的人。 :grin: 答案 [min & erisco] 就在彼此的下方。我看到了你对我的回答的回复,尽管我在同一个帖子中回复了。哦!我最初的评论是关于 *nix 对路径区分大小写(您对 strncmp 的引用和我对 strncasecmp 的回复)。我很抱歉造成混乱。
      【解决方案5】:

      不确定是否有内置函数。

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

      对于长 $str1 和短 $str2,我认为这会比使用 strpos 更快。

      如果您将它用于路径,您可能需要检查斜线是否在正确的位置。

      【讨论】:

        【解决方案6】:

        正则表达式呢?

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

        【讨论】:

          猜你喜欢
          • 2013-03-28
          • 2020-09-13
          • 2020-09-17
          • 2020-11-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-02-19
          相关资源
          最近更新 更多