PHP子字符串提取.在第一个'/'或整个字符串之前获取字符串

156 php string substring

我正在尝试提取子字符串.在PHP中我需要一些帮助.

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

home/cat1/subcat2 => home

test/cat2 => test

startpage => startpage
Run Code Online (Sandbox Code Playgroud)

我希望得到字符串直到第一个/,但如果没有/,请获取整个字符串.

我试过了,

substr($mystring, 0, strpos($mystring, '/'))
Run Code Online (Sandbox Code Playgroud)

我认为它说 - 获取位置,/然后从位置0到位置获取子串.

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

有没有办法处理这种情况,而不会使PHP语句太复杂?

jma*_*eli 256

最有效的解决方案是strtok功能:

strtok($mystring, '/')
Run Code Online (Sandbox Code Playgroud)

例如:

$mystring = 'home/cat1/subcat2/';
$first = strtok($mystring, '/');
echo $first; // home
Run Code Online (Sandbox Code Playgroud)

$mystring = 'home';
$first = strtok($mystring, '/');
echo $first; // home
Run Code Online (Sandbox Code Playgroud)

  • 这比"current-explode"解决方案快约40%.(不是我经常使用它而是重要的.) (23认同)
  • 这是优雅和快速 - 应该是公认的答案. (5认同)
  • 这应该是例外答案.绝对更快,更高的内存和CPU周期比任何给出的`explode`解决方案更有效. (5认同)
  • 在某些情况下这并不安全 - 例如尝试这个: `echo strtok("history_table_id","_id"); `。它仅返回“h”。当心! (2认同)

gnu*_*nud 235

使用 explode()

$arr = explode("/", $string, 2);
$first = $arr[0];
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我正在使用limit参数,explode以便php不会扫描字符串,而不是需要的.

  • `explode()+ [0]`是一种冗长的方式来编写`strtok($ string,"/")` (33认同)
  • 顺便说一下,你可以在php 5.5中爆炸("/",$ string,2)[0] (4认同)
  • 哦.好的.如果可能的话本来会很好. (3认同)
  • +1谢谢你的回答.它工作:)但一个问题.我只能这样做 - >`$ arr = explode('/',$ mystring,2); echo $ arr [0];`.我无法在一个语句中获得第一个字符串 - "echo explode('/',$ mystring,2)[0];`.由于explode返回一个数组,我应该能够做到这一点吗?但是我收到了一个错误.有什么建议? (2认同)
  • @mario `strtok()` 的问题是 `first/second` 将返回 `first`,但 `/second` 将返回 `second` 而不是空字符串。 (2认同)

小智 94

$first = explode("/", $string)[0];
Run Code Online (Sandbox Code Playgroud)

  • 优雅,但在计算机时间不是很有效.但是现在人们不再关心微小的CPU周期了 (2认同)

小智 11

那这个呢 :

substr($mystring.'/', 0, strpos($mystring, '/'))
Run Code Online (Sandbox Code Playgroud)

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


gly*_*yph 9

接受答案的单行版本:

$out=explode("/", $mystring, 2)[0];
Run Code Online (Sandbox Code Playgroud)

应该在php 5.4+中工作


pav*_*ich 8

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

list($first) = explode("/", $mystring);
Run Code Online (Sandbox Code Playgroud)

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

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

  • 我喜欢这种方法.保存制作不必要的数组.并且`strtok()`是不安全的. (2认同)

aim*_*mme 7

迟到总比没有好。php为此具有预定义的功能。这是个好方法。

strstr
Run Code Online (Sandbox Code Playgroud)

如果您想在比赛之前获得零件,只需将before_needle(第3个参数)设置为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', '/')
);
Run Code Online (Sandbox Code Playgroud)

  • 如果您不能确定绳子中是否存在针,则使用此方法是不安全的。 (2认同)

小智 5

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

$s = preg_replace('|/.*$|', '', $s);
Run Code Online (Sandbox Code Playgroud)

有时,正则表达式虽然较慢,但如果性能是一个问题,请确保对其进行适当的基准测试,并使用其他更适合您的子字符串替代方案。

  • 正则表达式也可能有点矫枉过正,但既然我对 `explode` 也这么说,那么看看哪个更快会很有趣。 (2认同)

小智 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 );
    }
}
Run Code Online (Sandbox Code Playgroud)

我没有测试它,但这应该工作得很好..而且它也很快

  • `strstr()`的+1,但是如果字符串不包含`$ needle`,请注意它返回`false`,因此上面的`explode()`解决方案更适合这种情况. (3认同)