Ekstraksi substring PHP. Dapatkan string sebelum '/' pertama atau seluruh string

170

Saya mencoba mengekstraksi substring. Saya butuh bantuan untuk melakukannya di PHP.

Berikut adalah beberapa string sampel yang saya kerjakan dan hasil yang saya butuhkan:

home/cat1/subcat2 => home

test/cat2 => test

startpage => startpage

Saya ingin mendapatkan string sampai yang pertama /, tetapi jika tidak /ada, dapatkan seluruh string.

Saya mencoba,

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

Saya pikir itu mengatakan - mendapatkan posisi /dan kemudian mendapatkan substring dari posisi 0 yang posisi.

Saya tidak tahu bagaimana menangani kasus di mana tidak ada /, tanpa membuat pernyataan terlalu besar.

Apakah ada cara untuk menangani kasus itu juga tanpa membuat pernyataan PHP terlalu rumit?


sumber
1
Anda mungkin menemukan s($str)->beforeFirst('/')bermanfaat, seperti yang ditemukan di perpustakaan mandiri ini .
gak

Jawaban:

261

Menggunakan explode()

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

Dalam hal ini, saya menggunakan limitparameter untuk explodesehingga php tidak akan memindai string lebih dari yang dibutuhkan.

Agak
sumber
2
+1 Terima kasih atas jawabannya. Berhasil :) Tapi satu pertanyaan. Saya hanya bisa melakukan ini -> $arr = explode('/',$mystring,2); echo $arr[0];. Saya tidak bisa mendapatkan string pertama dalam satu pernyataan itu sendiri - echo explode('/',$mystring,2)[0];. Karena explode mengembalikan array, saya harus bisa melakukannya dengan benar? Tapi saya mendapatkan kesalahan. Ada saran?
1
Php tidak suka Anda mengindeks ke nilai balik dari fungsi.
Gnud
3
oh baik. akan lebih baik jika itu mungkin.
36
explode() + [0]adalah cara bertele-tele untuk menulisstrtok($string, "/")
mario
5
Omong
293

Solusi yang paling efisien adalah strtokfungsinya:

strtok($mystring, '/')

Sebagai contoh:

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

dan

$mystring = 'home';
$first = strtok($mystring, '/');
echo $first; // home
Jmarceli
sumber
25
Ini juga sekitar 40% lebih cepat daripada current-explodesolusinya. (Bukannya saya sering menggunakannya sehingga penting.)
towr
5
Ini elegan dan cepat - harus menjadi jawaban yang diterima.
Kosta Kontos
5
Ini harus menjadi jawaban yang dikecualikan. Jelas lebih cepat dan lebih banyak memori dan siklus CPU efisien daripada explodesolusi yang diberikan.
Shivam Maheshwari
Masalah dengan strtokis first/secondakan kembali firsttetapi /secondakan kembali seconddaripada string kosong.
rybo111
Selanjutnya komentar saya di atas: Perilaku ketika bagian kosong ditemukan diubah dengan PHP 4.1.0. Perilaku lama mengembalikan string kosong, sedangkan perilaku baru, benar, hanya melewatkan bagian dari string
rybo111
95
$first = explode("/", $string)[0];
AndyBrandy
sumber
2
elegan, tetapi tidak terlalu efisien dalam waktu komputer. Tapi hari ini orang tidak peduli lagi tentang siklus CPU menit
Dennis
13

Bagaimana dengan ini :

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

Cukup tambahkan '/' pada akhir mistik sehingga Anda dapat yakin ada setidaknya satu;)

IRCF
sumber
Anda bisa memeriksa apakah ada satu tebasan di string sebelum melakukan ini. Bagaimanapun, itu solusi paling sederhana.
Guilherme Sampaio
12

Versi satu-baris dari jawaban yang diterima:

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

Harus bekerja di php 5.4+

mesin terbang
sumber
1
Berbeda dengan yang di bawah ini, "2" membatasi jumlah item array yang dibuatnya. Pemikiran yang bagus.
Ben di CA
9

Ini mungkin contoh terpendek yang muncul di benak saya:

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

1) list()akan secara otomatis menetapkan string sampai "/"jika pembatas ditemukan
2) jika pembatas "/"tidak ditemukan maka seluruh string akan ditetapkan

... dan jika Anda benar-benar terobsesi dengan kinerja, Anda dapat menambahkan parameter tambahan untuk meledak explode("/", $mystring, 2)yang membatasi maksimum elemen yang dikembalikan.

pavlovich
sumber
2
Saya suka pendekatan ini. Menghemat membuat array yang tidak perlu. Dan strtok()tidak aman.
rybo111
1
@ rybo111: Apa yang tidak aman strtok()?
hakre
@ rybo111 Saya menggemakan sentimen hakre; apa yang membuat strtok()tidak aman?
Doktor J
@hakre Lihat balasan saya untuk jawaban jmarceli. Itu dapat menyebabkan perilaku tak terduga tergantung pada versi PHP.
rybo111
php 4.1.0 - rly?
hakre
8

Terlambat lebih baik daripada tidak sama sekali. php memiliki fungsi yang telah ditentukan untuk itu. ini dia cara yang bagus.

strstr

jika Anda ingin mendapatkan bagian sebelum pertandingan cukup atur before_needle (parameter ke-3) ke 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', '/')
);
membidik
sumber
Ini tidak aman untuk digunakan jika Anda tidak dapat memastikan bahwa jarum ada di tali.
fooquency
@fooquency - Benar, tetapi Anda selalu dapat menambahkan karakter ke akhir string yang Anda periksa, hanya untuk memastikan.
MikeSchinkel
Terima kasih. Tes saya menunjukkan bahwa strstrsedikit lebih cepat daripada strtok. Saya akan pergi dengan yang pertama.
Ian Y.
5

Function strstr () di PHP 5.3 harus melakukan pekerjaan ini .. Namun parameter ketiga harus disetel ke true ..

Tetapi jika Anda tidak menggunakan 5.3, maka fungsi di bawah ini harus bekerja secara akurat:

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

Saya belum mengujinya, tetapi ini seharusnya bekerja dengan baik .. Dan ini juga cukup cepat

Ronald
sumber
3
Memberi +1 untuk strstr(), tetapi perlu diketahui bahwa itu kembali falsejika string tidak mengandung $needle, sehingga explode()solusi di atas lebih cocok dalam kasus ini.
Benjamin
3

Anda bisa membuat fungsi helper untuk mengatasinya:

/**
 * 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;
}

Berikut ini adalah use case:

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

echo str_before($sing, '.'); // My name is Luka
Toby Speight
sumber
3

Anda dapat mencoba menggunakan regex seperti ini:

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

kadang-kadang, regex lebih lambat, jadi jika kinerja merupakan masalah, pastikan untuk membandingkan ini dengan benar dan menggunakan alternatif lain dengan substring jika lebih cocok untuk Anda.

t00ny
sumber
2
Regex mungkin juga berlebihan, tetapi karena saya mengatakan hal yang sama tentang explodeitu akan menarik untuk melihat mana yang lebih cepat.
rvighne
1
sama sekali tidak ada yang salah dengan ini dan saya tidak bisa memikirkan mengapa itu layak mendapatkan 2 downvotes. Saya pribadi tidak akan menggunakan regex tetapi tentu saja tidak salah.
billynoah
2

Menggunakan currentpada explodeakan memudahkan proses.

 $str = current(explode("/", $str, 2));
pengguna1518659
sumber
0
$string="kalion/home/public_html";

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

Anda juga dapat menggunakan solusi satu baris ini

list($substring) = explode("/", $string);
Mas
sumber
-1

Saya pikir ini harus berhasil?

substr($mystring, 0, (($pos = (strpos($mystring, '/') !== false)) ? $pos : strlen($mystring)));
Franz
sumber
Fungsi Anda akan selalu mengembalikan char pertama karena Anda melakukan (strpos ($ mystring, '/')! == false) sebelum Anda menetapkannya ke $ pos, Anda perlu melakukan (($ pos = strpos ($ firstColumnName, '_'))! == false). Ini akan menjadi 1 liner yang dicari orang yang mengirim pertanyaan.
Mihai P.
-1

mengapa tidak menggunakan:

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

ATAU:

   function getwhatiwant($s)
   {
       $delimiter='/';
       $t=explode($delimiter, $s);
       return ($t[1]?$t[0]:$s);
   }
pengguna1123382
sumber