PHP部分文字列の抽出。最初の「/」の前の文字列または文字列全体を取得する


170

部分文字列を抽出しようとしています。PHPでそれを行うにはいくつかの助けが必要です。

ここで私が作業しているいくつかのサンプル文字列と必要な結果があります:

home/cat1/subcat2 => home

test/cat2 => test

startpage => startpage

最初まで文字列を取得したいのです/が、存在しない場合/は文字列全体を取得します。

私は試した、

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

私はそれが言っていると思います-の位置を/取得してから、位置0からその位置までの部分文字列を取得します。

/ステートメントが大きくなりすぎない限り、がない場合の処理​​方法がわかりません。

PHPステートメントを複雑にしすぎずにそのケースを処理する方法はありますか?


回答:


261

使用する explode()

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

この場合、phpが文字列を必要以上にスキャンしないようにlimitパラメーターを使用していますexplode


2
+1答えてくれてありがとう。それはうまくいった:)しかし、一つの質問。これしかできない-> $arr = explode('/',$mystring,2); echo $arr[0];。1つのステートメント自体の最初の文字列を取得できません- echo explode('/',$mystring,2)[0];。explodeは配列を返すので、正しく実行できるはずですか?しかし、エラーになります。助言がありますか?

1
PHPは、関数からの戻り値にインデックスを付けることを好みません。
gnud

3
ああ。はい。できればよかったのに。

36
explode() + [0]長い書き方ですstrtok($string, "/")
mario

5
ちなみに、php 5.5で
explode

292

最も効率的なソリューションですstrtok機能:

strtok($mystring, '/')

例えば:

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

そして

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

25
これは、current-explodeソリューションよりも約40%高速です。(重要なほど頻繁に使用しているわけではありません。)
2014年

5
これはエレガントで高速です-受け入れられるべき答えです。
Kosta Kontos

5
これは例外的な答えになるはずです。explode与えられたソリューションのどれよりも確実に高速で、より多くのメモリとCPUサイクルが効率的
Shivam Maheshwari

strtokis の問題first/secondは戻りますfirstが、空の文字列ではなく/second戻りsecondます。
rybo111 2016

上記の私のコメントに加えて:空の部分が見つかったときの動作は、PHP 4.1.0で変更されました。古い動作は空の文字列を返しましたが、新しい正しい動作は文字列の一部をスキップするだけです
rybo111

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

2
エレガントですが、コンピュータの時間ではあまり効率的ではありません。しかし、最近の人々はもはや分単位のCPUサイクルについてあまり気にしていません
Dennis

13

これはどうですか :

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

mystringの末尾に '/'を追加するだけで、少なくとも1つが存在することを確認できます;)


これを行う前に、文字列にスラッシュが1つあるかどうかを確認するだけです。とにかく、それは最も簡単な解決策です。
Guilherme Sampaio

12

受け入れられた回答の1行バージョン:

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

PHP 5.4以降で動作するはずです


1
以下のものとは異なり、「2」は作成する配列項目の数を制限します。いい考え。
カリフォルニア州ベン

9

これはおそらく私の頭に浮かんだ最も短い例です:

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

1)区切り文字が見つかるlist()まで文字列を自動的に割り当てます 2)"/"区切り文字が見つからない
場合"/"は、文字列全体が割り当てられます

...そして本当にパフォーマンスに夢中になったらexplode("/", $mystring, 2)、返される要素の最大値を制限する追加のパラメーターを爆発に追加することができます。


2
私はこのアプローチが好きです。不要な配列の作成を節約できます。そしてstrtok()、安全ではありません。
rybo111 2016

1
@ rybo111:何が安全ではないのstrtok()ですか?
2017年

@ rybo111私はハクルの感情を反映します。strtok()安全ではないものは何ですか?
Doktor J

@hakre jmarceliの回答に対する私の返信を参照してください。PHPのバージョンによっては、予期しない動作が発生する可能性があります。
rybo111 2017年

php 4.1.0-rly?
hakre 2017年

8

遅刻することは決してしないよりはましです。phpにはそのための定義済み関数があります。ここにその良い方法があります。

strstr

マッチ前のパーツを取得したい場合は、before_needle(3番目のパラメーター)をhttp://php.net/manual/en/function.strstr.phpに設定します。true

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

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

    return $buffer;
}

var_dump(
    not_strtok('st/art/page', '/')
);

これは、針が文字列に存在することを確認できない場合は安全ではありません。
fooquency

@fooquency — True、ただし念のため、チェックする文字列の末尾にいつでも文字を追加できます。
MikeSchinkel

ありがとう。私のテストでは、それstrstrがよりわずかに速いことを示しましたstrtok。前者でいきます。
Ian Y.

5

PHP 5.3の関数strstr()はこの作業を行う必要があります。ただし、3番目のパラメータはtrueに設定する必要があります。

ただし、5.3を使用していない場合は、以下の関数が正確に機能するはずです。

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

私はそれをテストしていませんが、これはうまく動作するはずです。そして、それもかなり高速です


3
+1 for strstr()ですがfalse、文字列にが含まれていない場合に返されることに注意してください。この場合、上記$needleexplode()ソリューションの方が適しています。
ベンジャミン

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

3

次のような正規表現を使用してみてください:

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

ただし、正規表現の方が遅い場合もあります。そのため、パフォーマンスに問題がある場合は、これを適切にベンチマークし、適切な場合は部分文字列を使用した他の代替手段を使用してください。


2
正規表現もおそらくやり過ぎですが、私が同じことを言っているので、explodeどちらが速いかを見るのは興味深いでしょう。
rvighne 2014年

1
これには何の問題もありません。なぜ2票に値するのか、私には思いつきません。私は個人的に正規表現を使用しませんが、それは確かに間違っていません。
ビリーノア2016

2

currenton explodeを使用すると、プロセスが簡単になります。

 $str = current(explode("/", $str, 2));

0
$string="kalion/home/public_html";

$newstring=( stristr($string,"/")==FALSE ) ? $string : substr($string,0,stripos($string,"/"));

0

この1行のソリューションを使用することもできます

list($substring) = explode("/", $string);

-1

これはうまくいくと思いますか?

substr($mystring, 0, (($pos = (strpos($mystring, '/') !== false)) ? $pos : strlen($mystring)));

$ posに割り当てる前に(strpos($ mystring、 '/')!== false)を実行しているため、関数は常に最初の文字を返します。(($ pos = strpos($ firstColumnName、 '_'))!== false)。これは、質問を投稿した人が探している1つのライナーです。
Mihai P.

-1

なぜ使用しない:

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);
   }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.