Hapus string dari awal string

146

Saya memiliki string yang terlihat seperti ini:

$str = "bla_string_bla_bla_bla";

Bagaimana saya bisa menghapus yang pertama bla_; tetapi hanya jika itu ditemukan di awal string?

Dengan str_replace(), itu menghapus semua bla_ .

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

Jawaban:

339

Bentuk polos, tanpa regex:

$prefix = 'bla_';
$str = 'bla_string_bla_bla_bla';

if (substr($str, 0, strlen($prefix)) == $prefix) {
    $str = substr($str, strlen($prefix));
} 

Membawa: 0,0369 ms (0,000,036,954 detik)

Dan dengan:

$prefix = 'bla_';
$str = 'bla_string_bla_bla_bla';
$str = preg_replace('/^' . preg_quote($prefix, '/') . '/', '', $str);

Membawa: 0,1749 ms (0,000,174,999 detik) run pertama (kompilasi), dan 0,0510 ms (0,000,051,021 detik) setelahnya.

Diprofilkan di server saya, jelas.

Fabio Mora
sumber
8
Saya belum pernah melihat operator ternary dilecehkan begitu buruk, sederhana if(condition) { statement }akan jauh lebih jelas.
Tatu Ulmanen
4
@salathe: Saya menerima kritik. Itu adalah keingintahuan pribadi untuk melihat apa yang tercepat.
Fabio Mora
51
@salathe, saya tidak mengerti. Kedua solusi berbasis idiomatik dan regex diusulkan: membandingkan keduanya dalam hal efisiensi membantu menemukan jawaban terbaik (lagi dalam hal efisiensi). Mengapa itu jahat?
cbrandolino
5
@cbrandolino, tidak ada yang mengatakan itu jahat . Saya hanya berpikir itu sama sekali tidak relevan dengan pertanyaan; seperti "di sini ada dua solusi, dan inilah gambar beberapa anak kucing untuk mendapatkan lebih banyak suara".
salathe
5
if (substr($str, 0, strlen($prefix)) == $prefix) dapat diubah untuk if (0 === strpos($str, $prefix))menghindari alokasi memori yang tidak perlu sambil menjaga keterbacaan yang sama :)
xDaizu
63

Anda bisa menggunakan ekspresi reguler dengan simbol tanda sisipan ( ^) yang mengaitkan kecocokan ke awal string:

$str = preg_replace('/^bla_/', '', $str);
Tatu Ulmanen
sumber
Saya ingin tahu apakah ini bekerja lebih cepat daripada substr()versi ... Saya kira itu berhasil, dan harus ditandai sebagai jawaban yang tepat.
Flash Thunder
kecuali itu harus preg_quote'd
vp_arth
Saya pikir ini jauh lebih menyakitkan bagi mata seorang programmer dan lebih intuitif. Bahkan jika itu kehilangan kinerja untuk solusi lain yang disarankan (yang saya benar-benar ragu), saya masih lebih suka ini
Fr0zenFyr
multibytemimpi buruk adalah masalah lain dengan solusi lain sementara ini bekerja dengan baik jika penyandian file sudah benar. Bagaimanapun, itu seharusnya tidak berada dalam lingkup pertanyaan ini jadi saya tidak akan peduli.
Fr0zenFyr
Kembali lagi untuk menyebutkan bahwa ini memiliki manfaat tambahan bekerja dengan berbagai string subjek. substrdan strpostidak dapat menerima array. Ini dia, keuntungan kinerja yang pasti jika Anda berurusan dengan sebuah array. Bersulang!
Fr0zenFyr
20
function remove_prefix($text, $prefix) {
    if(0 === strpos($text, $prefix))
        $text = substr($text, strlen($prefix)).'';
    return $text;
}
Pavel
sumber
10
Tidak .''diperlukan.
NateS
1
Untuk apa nilainya karena setiap orang tampaknya mengoptimalkan mikro di sini, yang satu ini secara konsisten tercepat menurut hitungan saya. 1 juta iterasi muncul pada, 17 detik, sedangkan (substr($str, 0, strlen($prefix)) == $prefix)dari jawaban yang diterima lebih seperti
0,37
5

Sini.

$array = explode("_", $string);
if($array[0] == "bla") array_shift($array);
$string = implode("_", $array);
cbrandolino
sumber
2
Mengukur 0,0000459153 detik :)
Fabio Mora
Kecepatan bagus, tapi ini kode keras bergantung pada jarum yang diakhiri _. Apakah ada versi umum?
toddmo
0

Saya pikir substr_replace melakukan apa yang Anda inginkan, di mana Anda dapat membatasi penggantian Anda ke bagian dari string Anda: http://nl3.php.net/manual/en/function.substr-replace.php (Ini akan memungkinkan Anda untuk hanya melihat awal dari string.)

Anda dapat menggunakan parameter hitungan str_replace ( http://nl3.php.net/manual/en/function.str-replace.php ), ini akan memungkinkan Anda untuk membatasi jumlah penggantian, mulai dari kiri, tetapi tidak akan memberlakukannya di awal.

Inca
sumber
1
substr_replaceakan mengganti karakter dalam rentang yang diberikan terlepas dari apakah mereka awalan yang ingin Anda hapus atau sesuatu yang lain. OP ingin menghapus bla_"hanya jika ditemukan di awal string."
Olivier 'Ölbaum' Scherler
0

Kecepatan bagus, tapi ini kode keras bergantung pada jarum yang diakhiri dengan _. Apakah ada versi umum? - toddmo 29 Jun pukul 23:26

Versi umum:

$parts = explode($start, $full, 2);
if ($parts[0] === '') {
    $end = $parts[1];
} else {
    $fail = true;
}

Beberapa tolok ukur:

<?php

$iters = 100000;
$start = "/aaaaaaa/bbbbbbbbbb";
$full = "/aaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee";
$end = '';

$fail = false;

$t0 = microtime(true);
for ($i = 0; $i < $iters; $i++) {
    if (strpos($full, $start) === 0) {
        $end = substr($full, strlen($start));
    } else {
        $fail = true;
    }
}
$t = microtime(true) - $t0;
printf("%16s : %f s\n", "strpos+strlen", $t);

$t0 = microtime(true);
for ($i = 0; $i < $iters; $i++) {
    $parts = explode($start, $full, 2);
    if ($parts[0] === '') {
        $end = $parts[1];
    } else {
        $fail = true;
    }
}
$t = microtime(true) - $t0;
printf("%16s : %f s\n", "explode", $t);

Di PC rumah saya yang cukup lama:

$ php bench.php

Output:

   strpos+strlen : 0.158388 s
         explode : 0.126772 s
Aleksandar Bosakov
sumber
0

Inilah pendekatan yang bahkan lebih cepat:

// strpos is faster than an unnecessary substr() and is built just for that 
if (strpos($str, $prefix) === 0) $str = substr($str, strlen($prefix));
Stefan Gabos
sumber
0

Ini akan menghapus kecocokan pertama di mana pun ia ditemukan yaitu, mulai atau tengah atau akhir.

$str = substr($str, 0, strpos($str, $prefix)).substr($str, strpos($str, $prefix)+strlen($prefix));
Muzaffar Mahmood
sumber
-1
<?php
$str = 'bla_string_bla_bla_bla';
echo preg_replace('/bla_/', '', $str, 1); 
?>
Bhanu Prakash Pandey
sumber
-6

str_replace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] )

sekarang lakukan apa yang kamu mau.

$str = "bla_string_bla_bla_bla";
str_replace("bla_","",$str,1);
Rawa
sumber
7
The str_replace()Fungsi ini $countparameter diharapkan menjadi variabel dikirimkan dengan referensi mengandung jumlah pengganti ditemukan, tidak membatasi jumlah pengganti.
AL X
-6

Hapus www. dari awal string, ini adalah cara termudah (ltrim)

$a="www.google.com";
echo ltrim($a, "www.");
pengguna1016724
sumber
8
Parameter kedua adalah peta karakter yang akan dihapus dari sisi kiri string ( php.net/manual/function.ltrim.php ). Karenanya: ltrim($a, "w.");akan melakukan pekerjaan hanya jika domain tidak akan memulai dengan "w". ltrim ('m.google.com', ".omg")hasil dalam le.com.
terfragmentasi
tetapi itu memecahkan masalah khusus dari pertanyaan, +1
chulian
1
itu benar-benar memecahkan masalah khusus yang dia buat untuk jawabannya - bukan masalah pertanyaannya. bahkan jika Anda mau ltrim, itu digunakan secara tidak benar. parameter kedua adalah daftar karakter yang harus dipangkas; karena itu satu "w."saja sudah cukup.
fragmentedreality
Saya pikir, IMHO, itu benar untuk pertanyaan dan masalah.
abkrim
2
Setelah tes dengan beberapa tes, ubah pendapat saya .... tidak berfungsi untuk pertanyaan pada situasi apa pun
abkrim