199

我正在尝试提取子字符串。我需要一些帮助来用 PHP 做这件事。

以下是我正在使用的一些示例字符串以及我需要的结果:

home/cat1/subcat2 => home

test/cat2 => test

startpage => startpage

我想获取字符串直到第一个/,但如果不/存在,则获取整个字符串。

我试过,

substr($mystring, 0, strpos($mystring, '/'))

我认为它说 - 获取位置,/然后将子字符串从位置 0 获取到位置。

我不知道如何处理没有的情况/,而不会使声明太大。

有没有办法在不使 PHP 语句过于复杂的情况下处理这种情况?

4

13 回答 13

357

有效的解决方案是strtok函数:

strtok($mystring, '/')

注意:如果要拆分多个字符,结果可能不符合您的期望,例如strtok("somethingtosplit", "to")返回s,因为它是由第二个参数中的任何单个字符拆分的(在这种情况下o使用)。

@friek108 感谢您在评论中指出这一点。

例如:

$mystring = 'home/cat1/subcat2/';
$first = strtok($mystring, '/');
echo $first; // home

$mystring = 'home';
$first = strtok($mystring, '/');
echo $first; // home
于 2014-06-18T08:03:57.157 回答
291

采用explode()

$arr = explode("/", $string, 2);
$first = $arr[0];

在这种情况下,我使用该limit参数来explode使 php 不会扫描超出需要的字符串。

于 2009-12-20T14:11:03.063 回答
102
$first = explode("/", $string)[0];
于 2011-12-30T12:18:17.120 回答
16

那这个呢 :

substr($mystring.'/', 0, strpos($mystring, '/'))

只需在 mystring 的末尾添加一个“/”,这样您就可以确定至少有一个;)

于 2011-03-30T14:25:54.467 回答
14

迟到总比没有好。php 有一个预定义的函数。这是一个好方法。

strstr

如果您想在匹配之前获取部分,只需将before_needle(第三个参数)设置为true http://php.net/manual/en/function.strstr.php

function not_strtok($string, $delimiter)
{    
    $buffer = strstr($string, $delimiter, true);

    if (false === $buffer) {
        return $string;
    }

    return $buffer;
}

var_dump(
    not_strtok('st/art/page', '/')
);
于 2016-03-29T03:24:11.453 回答
12

接受答案的单行版本:

$out=explode("/", $mystring, 2)[0];

应该在 php 5.4+ 中工作

于 2017-02-28T00:05:42.760 回答
9

这可能是我想到的最短的例子:

list($first) = explode("/", $mystring);

1)list()将自动分配字符串,直到"/"找到分隔符
2) 如果"/"未找到分隔符,则分配整个字符串

...如果你真的痴迷于性能,你可以添加额外的参数来爆炸explode("/", $mystring, 2),这限制了返回元素的最大值。

于 2015-04-23T14:18:33.310 回答
5

您可以尝试使用这样的正则表达式:

$s = preg_replace('|/.*$|', '', $s);

有时,正则表达式会比较慢,所以如果性能是一个问题,请确保正确地对其进行基准测试,如果它更适合您,请使用带有子字符串的其他替代方法。

于 2009-12-20T14:50:32.163 回答
5

PHP 5.3 中的函数 strstr() 应该可以完成这项工作。但是第三个参数应该设置为 true。

但是如果你没有使用 5.3,那么下面的函数应该可以正常工作:

function strbstr( $str, $char, $start=0 ){
    if ( isset($str[ $start ]) && $str[$start]!=$char ){
        return $str[$start].strbstr( $str, $char, $start+1 );
    }
}

我还没有测试过,但这应该可以正常工作..而且速度也很快

于 2011-03-08T15:18:02.137 回答
3

使用currentonexplode会简化这个过程。

 $str = current(explode("/", $str, 2));
于 2012-12-31T07:14:09.783 回答
3

您可以创建一个辅助函数来解决这个问题:

/**
 * Return string before needle if it exists.
 *
 * @param string $str
 * @param mixed $needle
 * @return string
 */
function str_before($str, $needle)
{
    $pos = strpos($str, $needle);

    return ($pos !== false) ? substr($str, 0, $pos) : $str;
}

这是一个用例:

$sing = 'My name is Luka. I live on the second floor.';

echo str_before($sing, '.'); // My name is Luka
于 2016-08-24T13:16:11.653 回答
-1
$string="kalion/home/public_html";

$newstring=( stristr($string,"/")==FALSE ) ? $string : substr($string,0,stripos($string,"/"));
于 2010-11-20T13:06:09.200 回答
-2

为什么不使用:

function getwhatiwant($s)
{
    $delimiter='/';
    $x=strstr($s,$delimiter,true);
    return ($x?$x:$s);
}

或者:

   function getwhatiwant($s)
   {
       $delimiter='/';
       $t=explode($delimiter, $s);
       return ($t[1]?$t[0]:$s);
   }
于 2013-08-19T18:44:26.490 回答