【问题标题】:Trim only the first and last occurrence of a character in a string (PHP)仅修剪字符串中第一次和最后一次出现的字符 (PHP)
【发布时间】:2011-04-19 13:23:55
【问题描述】:

这是我可以一起破解的东西,但我想知道是否有人对我的问题有一个干净的解决方案。我拼凑起来的东西不一定非常简洁或快速!

我有一个像 ///hello/world/// 这样的字符串。我只需要去掉第一个和最后一个斜杠,其他的都不需要,这样我就得到了一个像 //hello/world// 这样的字符串。

PHP 的 trim 不太正确:执行 trim($string, '/') 将返回 hello/world

需要注意的一点是,字符串的开头或结尾不一定有任何斜线。以下是我希望不同字符串发生的一些示例:

///hello/world/// > //hello/world//
/hello/world/// > hello/world//
hello/world/ > hello/world

提前感谢您的帮助!

【问题讨论】:

  • 为什么不带一个真实世界的例子而不是这样一个假的呢?可能有更好的解决方案,仅适用于您的情况吗?一个真实的案例。
  • @col 这几乎是真实的世界。它是路由类的一部分,它通过当前 URL 路径路由到适当的控制器。我刚刚注意到http://example.com/path/to/file 解析为与http://example.com///path/to/file// 相同的控制器,所以上面的示例几乎正是我得到的字符串的样子:) 我正在处理路径
  • 但是有这么多个斜线的原因是什么?路径只需要一个。我从未见过这样的路径:///path/to/file//。你从哪里得到它们,你为什么不想要规范化,使其成为通常的 /path/to/file/?
  • 哦,我不想要斜线。我在想非常极端的情况,比如有人输入错误的 URL。目前,我正在寻找的功能与配置相关联,因此可以逐个应用程序更改行为。也许我想太多了,但无论如何我都得到了我的问题的答案,所以我很高兴。我相信有一天我会有另一个用途!

标签: php string trim


【解决方案1】:

这是迄今为止最简单的一个。它匹配 ^/(开始斜线)和 /$(结束斜线),如果找到任何一个,则将其替换为空字符串。这适用于任何角色;只需将以下正则表达式中的 / 替换为您选择的字符即可。请注意我使用 # 而不是 / 的分隔符,以使其更易于阅读。这将从字符串中删除任何单个的第一个或最后一个 /:

$trimmed = preg_replace('#(^/|/$)#', '', $string);

结果:

///hello/world/// > //hello/world//
/hello/world/// > hello/world//
hello/world/ > hello/world

【讨论】:

    【解决方案2】:

    此功能作为官方修剪,只是它只修剪一次。

    function trim_once($text, $c) {
        $c = preg_quote($c);
        return preg_replace("#^([$c])?(.*?)([$c])?$#", '$2', $text);
    }
    
    php > echo trim_once("||1|2|3|*", "*|");
    |1|2|3|
    php > echo trim_once("//|1|2|3/", "/");
    /|1|2|3
    

    【讨论】:

      【解决方案3】:

      已经超过 6 年了,但我给出的答案可能还是会:

      function trimOnce($value)
      {   
          $offset = 0;
          $length = null;
          if(mb_substr($value,0,1) === '/') {
              $offset = 1;
          }
          if(mb_substr($value,-1) === '/') {
             $length = -1;
          }
          return mb_substr($value,$offset,$length);
      }
      

      【讨论】:

        【解决方案4】:

        又一个实现:

        function otrim($str, $charlist)
        {
         return preg_replace(sprintf('~^%s|%s$~', preg_quote($charlist, '~')), '', $str);
        }
        

        【讨论】:

        • 这给了我Fatal error: Uncaught ErrorException: sprintf(): Too few arguments
        【解决方案5】:

        一个不同的正则表达式,使用反向引用:

        preg_replace('/^(\/?)(.*)\1$/','\2',$text);
        

        这样做的好处是,如果您想使用 / 以外的字符,您可以更清晰地使用。它还强制 / 字符开始和结束字符串,并允许 / 出现在字符串中。最后,如果结尾也有字符,它只会从开头删除字符,反之亦然。

        【讨论】:

          【解决方案6】:

          我想这就是你要找的东西:

          preg_replace('/\/(\/*[^\/]*?\/*)\//', '\1', $text);
          

          【讨论】:

          • 啊,你不能只切换分隔符吗? #/(/*[^/]*?/*)/#。但是,您忘记锚定它:#^/(/*[^/]*?/*)$/#,为了有效起见,您不妨使用preg_replace('#(^/|/$)#','',$text);
          • /\/(\/*[^\/]*?\/*)\//#(^/|/$)# 之间的区别是为什么人们会很快将正则表达式视为不可读。
          【解决方案7】:

          我想到的第一件事:

          if ($string[0] == '/') $string = substr($string,1);
          if ($string[strlen($string)-1] == '/') $string = substr($string,0,strlen($string)-1);
          

          【讨论】:

          • 我相信 substring 方法可能会比正则表达式运行得快很多。
          • 这是我自己总结的非常粗略的内容。如果正则表达式会变慢,我想避免使用正则表达式,是否有任何统计数据可以支持简单字符串操作函数与正则表达式的速度?
          • @Rowan:不,没有这样的统计数据,因为它非常取决于正在进行的实际操作,有时正则表达式确实会获胜。唯一的判断方法是针对您预期的字符串对其进行基准测试,即使那样我会说基于性能使用一个而不是另一个可能是微优化。
          • @Kevin 仅当有数千行这样的行时。优秀的程序员应该避免这样的数字。
          • 太棒了,非常感谢。我之前被警告过不要进行微优化:)
          猜你喜欢
          • 1970-01-01
          • 2015-06-13
          • 2022-01-13
          • 2017-08-20
          • 2013-12-28
          • 2012-05-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多