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.