Bir dizgiyi dizenin başından kaldırma


Yanıtlar:


339

Normal ifade olmadan düz form:

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

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

Almak : 0.0369 ms (0.000.036.954 saniye)

Ve birlikte:

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

Alır: 0,1749 ms (0.000,174,999 saniye) (derleme) 1 işletilen ve 0,0510 ms (0.000,051,021 saniye) sonra.

Açıkçası, benim sunucu profilli.


8
Üçlü operatörün bu kadar kötüye kullanıldığını hiç görmedim, basit bir if(condition) { statement }şey çok daha açık olurdu.
Tatu Ulmanen

4
@salathe: Eleştiriyi kabul ediyorum. En hızlı olanı görmek kişisel bir meraktı.
Fabio Mora

51
@ salathe, anlamadım. Hem deyimsel hem de regex tabanlı çözümler önerildi: ikisini verimlilik açısından karşılaştırmak (yine verimlilik açısından) en iyi cevabı bulmaya yardımcı olur. Neden bu kötülük?
cbrandolino

5
@cbrandolino, kimse kötü olduğunu söylemedi . Sadece soru ile tamamen alakasız olduğunu düşündüm; "işte iki çözüm var ve burada daha fazla oy için bazı yavru kedi resmi" olurdu.
Aralık'ta salathe

5
if (substr($str, 0, strlen($prefix)) == $prefix) if (0 === strpos($str, $prefix))aynı okunabilirliği korurken gereksiz bellek ayırmayı önlemek için değiştirilebilir :)
xDaizu

63

Eşleşmeyi ^dizenin başına bağlayan düzeltme işareti sembolüyle ( ) normal ifadeler kullanabilirsiniz :

$str = preg_replace('/^bla_/', '', $str);

Sürümden daha hızlı çalışıp çalışmadığını merak ediyorum substr()... Sanırım çalışıyor ve uygun cevap olarak işaretlenmesi gerekiyor.
Flash Thunder

dışında preg_quote'd
vp_arth

Bence bu bir programcının gözleri için daha az acı verici ve daha sezgisel. Performansta başka bir önerilen çözüme (gerçekten şüphelendiğim) kaybedse bile, yine de bunu tercih ederim.
Fr0zenFyr

multibytekabus diğer çözümlerle ilgili başka bir sorundur, ancak dosyanın kodlaması doğru ise iyi çalışır. Her neyse, bu sorunun kapsamına girmemeliydi bu yüzden umursamam.
Fr0zenFyr

Bunun bir dizi konu dizesiyle çalışmanın ek bir yararı olduğunu belirtmek için geri döndü. substrve strposbir diziyi kabul edemez. İşte bir dizi ile uğraşıyorsanız, kesin bir performans kazancı. Şerefe!
Fr0zenFyr

20
function remove_prefix($text, $prefix) {
    if(0 === strpos($text, $prefix))
        $text = substr($text, strlen($prefix)).'';
    return $text;
}

10
Gerek .''yok.
NateS

1
Her biri burada mikro optimizasyon yapıyormuş gibi göründüğü için, bu sayıma göre sürekli en hızlı. 1 milyon iterasyon (substr($str, 0, strlen($prefix)) == $prefix)
0,17

5

Buraya.

$array = explode("_", $string);
if($array[0] == "bla") array_shift($array);
$string = implode("_", $array);

2
Tedbir 0.0000459153 saniye :)
Fabio Mora

Güzel hız, ancak bu ile biten iğneye bağlı olarak sabit kodlanmıştır _. Genel bir sürümü var mı?
toddmo

0

Bence substr_replace istediğini yapıyor, senin yerine senin dize bir parçası ile sınırlayabilirsiniz: http://nl3.php.net/manual/en/function.substr-replace.php (Bu sadece bakmak için sağlayacaktır dizenin başlangıcı.)

Str_replace ( http://nl3.php.net/manual/en/function.str-replace.php ) count parametresini kullanabilirsiniz; bu, soldan başlayarak değiştirme sayısını sınırlamanıza izin verir, ancak başlangıçta olmasını zorunlu kılmaz.


1
substr_replacekaldırmak istediğiniz önek olsun ya da başka bir şey olsun, verilen aralıktaki karakterlerin yerini alacaktır. OP bla_“yalnızca dizenin başında bulunursa” kaldırmak istiyor .
Olivier 'Ölbaum' Scherler

0

Güzel hız, ancak bu _ ile biten iğneye bağlı olarak kodlanmıştır. Genel bir sürümü var mı? - toddmo 29 Haziran, 23:26

Genel bir versiyon:

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

Bazı kriterler:

<?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);

Oldukça eski ev bilgisayarımda:

$ php bench.php

Çıktılar:

   strpos+strlen : 0.158388 s
         explode : 0.126772 s

0

İşte daha hızlı bir yaklaşım:

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

0

Böylece ilk maç nerede bulunursa bulunsun, yani başlangıç, orta veya bitiş.

$str = substr($str, 0, strpos($str, $prefix)).substr($str, strpos($str, $prefix)+strlen($prefix));


-6

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

şimdi ne istersen yapar.

$str = "bla_string_bla_bla_bla";
str_replace("bla_","",$str,1);

7
str_replace()İşlevin $countparametresi bir yedek sayısını içeren referans ile geçirilen değişken bulunan olması beklenmektedir, değiştirme sayısını sınırlamak değil.
AL the X

-6

Www. dizenin başından itibaren, bu en kolay yol (ltrim)

$a="www.google.com";
echo ltrim($a, "www.");

8
İkinci parametre, dizenin sol tarafından kaldırılacak karakterlerin haritasıdır ( php.net/manual/function.ltrim.php ). Bu nedenle: ltrim($a, "w.");işi yalnızca etki alanı "w" ile başlamazsa yapar. ltrim ('m.google.com', ".omg")ile sonuçlanır le.com.
fragmentedreality

ancak sorunun özel sorununu çözer, +1
chulian

1
sorunun cevabı için yaptığı problemi çözüyor - sorunun sorunu değil. birlikte gitseniz bile ltrimyanlış kullanılır. ikinci parametre, kesilmesi gereken karakterlerin listesidir; bu nedenle bir single "w."yeterli olacaktır.
fragmentedreality

Bence IMHO, soru ve sorun için doğru.
abkrim

2
Birkaç test ile testten sonra fikrimi değiştirdim .... herhangi bir durumda soru için çalışmıyor
abkrim
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.