Yolu dize doğrudan alt dizinini

3 Cevap php

Ben tam yol dizeden doğrudan alt dizinin adını ayıklamak gerekir.

Örneğin, bunu söylüyor:

$str = "dir1/dir2/dir3/dir4/filename.ext";
$dir = "dir1/dir2";

Sonra dir $ için $ str izde alt dizinin ismi "Dir3" olacaktır. O $ dir ucunda '/' asla unutmayın.

Yani işlevi olmalıdır:

$subdir = getsubdir($str,$dir);
echo $subdir; // Outputs "dir3"

$ Dir = "dir1" sonra çıktı "dir2" olurdu. $ Dir = "dir1/dir2/dir3/dir4" sonra çıktı "" (boş) olurdu. $ Dir Eğer = "dir1" "sonra çıkış olacaktır". Vb.

Şu anda bu ben ne var, ve (bildiğim kadarıyla bunu test ettik gibi) çalışır. Ben string fonksiyonları bir sürü kullanıyorum bulmak beri basit bir yolu olup olmadığını merak ediyorum. Belki bir satırda bunun için bazı sihirli sıradanifade var? (Ne yazık ki regexp ile çok iyi değilim).

function getsubdir($str,$dir) {
    // Remove the filename
    $str = dirname($str);

    // Remove the $dir
    if(!empty($dir)){
        $str = str_replace($dir,"",$str);
    }

    // Remove the leading '/' if there is one
    $si = stripos($str,"/");
    if($si == 0){
        $str = substr($str,1);
    }

    // Remove everything after the subdir (if there is anything)
    $lastpart = strchr($str,"/");
    $str = str_replace($lastpart,"",$str);

    return $str;
}

Gördüğünüz gibi, bu (giriş yok '/', boş girişi, vb) bazı garip davalarını için biraz hacky bulunuyor. Ben mantıklı hepsi umuyoruz. Herhangi bir yardım / öneri bekliyoruz.

Update (altered solution):

Peki Alix Axel o nokta üzerinde oldu. (: O) sadece dizinleri değil dosyaları (çıktılanmasını, bir dize döndürmek gerekir gibi) benim tam gereksinimleri ile uyumlu olduğunu, bu nedenle burada hafif tweaks ile yaptığı çözüm

function getsubdir($str,$dir) {
    $str = dirname($str);
    $temp = array_slice(array_diff(explode('/', $str), explode('/', $dir)), 0, 1);
    return $temp[0];   
}

3 Cevap

Buyrun:

function getSubDir($dir, $sub)
{
    return array_slice(array_diff(explode('/', $dir), explode('/', $sub)), 0, 1);
}

EDIT - Foolproof implementation:

function getSubDirFoolproof($dir, $sub)
{
    /*
    This is the ONLY WAY we have to make SURE that the
    last segment of $dir is a file and not a directory.
    */
    if (is_file($dir))
    {
        $dir = dirname($dir);
    }

    // Is it necessary to convert to the fully expanded path?
    $dir = realpath($dir);
    $sub = realpath($sub);

    // Do we need to worry about Windows?
    $dir = str_replace('\\', '/', $dir);
    $sub = str_replace('\\', '/', $sub);

    // Here we filter leading, trailing and consecutive slashes.
    $dir = array_filter(explode('/', $dir));
    $sub = array_filter(explode('/', $sub));

    // All done!
    return array_slice(array_diff($dir, $sub), 0, 1);
}

Nasıl bir diziye şeyi bölme hakkında:

$fullpath = explode("/", "dir1/dir2/dir3/dir4/filename.ext");
$fulldir  = explode("/", "dir1/dir2");

// Will result in array("dir1","dir2","dir3", "dir4", "filename.ext");
// and            array("dir1", "dir2");

Eğer kullanmak mümkün olacak array_diff() olmalıdır:

$remainder = array_diff($fullpath, $fulldir);

// Should return array("dir3", "dir4", "filename.ext");

Daha sonra, doğrudan çocuğu almak kolaydır:

echo $remainder[0];

Ben şimdi bu hakkı test edemez ama çalışması gerekir.

İşte dize işlevlerini yerine dizi fonksiyonlarını kullanarak benzer bir "kısa" bir çözüm, bu sefer. Dizeden kazanılmış hiçbir karşılık parçası varsa, getsubdir dönecektir FALSE. strtr segmenti sscanf için özel anlama sahip yüzdeleri, kaçmak için hızlı bir yoldur.

function getsubdir($str, $dir) {
    return sscanf($str, strtr($dir, '%', '%%').'/%[^/]', $name) === 1 ? $name : FALSE;
}

Ve hızlı bir test öylesine sen nasıl davrandığını görebilirsiniz:

$str = "dir1/dir2/dir3/dir4/filename.ext";
var_dump(
    getSubDir($str, "dir1"),
    getSubDir($str, "dir1/dir2/dir3"),
    getSubDir($str, "cake")
);
// string(4) "dir2"
// string(4) "dir4"
// bool(false)