Seçeneklerin sınırsız sayıda maç Düzenli İfade

5 Cevap php

Ben bu gibi dosya yollarını ayrıştırmak mümkün olmak istiyorum:

 /var/www/index.(htm|html|php|shtml)

Sıralı bir diziye:

 array("htm", "html", "php", "shtml")

ve daha sonra alternatif bir listesini üretmek:

/var/www/index.htm
/var/www/index.html
/var/www/index.php
/var/www/index.shtml

Şu anda, ben two alternatifler bölebilirsiniz preg_match bildirimde:

 preg_match_all ("/\(([^)]*)\|([^)]*)\)/", $path_resource, $matches);

Biri bana alternatif bir unlimited sayıda (en az iki) kabul etmek için bu uzatmak için nasıl bir işaretçi verebilir misiniz? Sadece düzenli ifade ile ilgili, geri kalanı ben başa çıkabilirim.

Kural şudur:

  • Liste ) ile ( ve yakın ile başlamak gerekiyor

  • Listede (yani en az iki alternatif) bir | olmalı

  • ( veya ) diğer herhangi bir olay (lar) bakir kalacak.

Update: Ben de gibi birden fazla ayraç çifti ile başa çıkabilmek gerekir:

 /var/(www|www2)/index.(htm|html|php|shtml)

üzgünüm hemen söylemedim.

Eğer ben dosya sistemi yapmak için çalışıyorum ne yapmak arıyorsanız Update 2:, o glob () zaten kutudan bu işlevlerini getiriyor unutmayın. Özel bir solutiom uygulamak için gerek yoktur. Ayrıntılar için aşağıdaki Gordon'un cevabını @ bakın.

5 Cevap

Sigara regex çözüm :)

<?php

$test = '/var/www/index.(htm|html|php|shtml)';

/**
 *
 * @param string $str "/var/www/index.(htm|html|php|shtml)"
 * @return array "/var/www/index.htm", "/var/www/index.php", etc
 */
function expand_bracket_pair($str)
{
    // Only get the very last "(" and ignore all others.
    $bracketStartPos = strrpos($str, '(');
    $bracketEndPos = strrpos($str, ')');

    // Split on ",".
    $exts = substr($str, $bracketStartPos, $bracketEndPos - $bracketStartPos);
    $exts = trim($exts, '()|');
    $exts = explode('|', $exts);

    // List all possible file names.
    $names = array();

    $prefix = substr($str, 0, $bracketStartPos);
    $affix = substr($str, $bracketEndPos + 1);
    foreach ($exts as $ext)
    {
        $names[] = "{$prefix}{$ext}{$affix}";
    }

    return $names;
}

function expand_filenames($input)
{
    $nbBrackets = substr_count($input, '(');

    // Start with the last pair.
    $sets = expand_bracket_pair($input);

    // Now work backwards and recurse for each generated filename set.
    for ($i = 0; $i < $nbBrackets; $i++)
    {
        foreach ($sets as $k => $set)
        {
            $sets = array_merge(
                $sets,
                expand_bracket_pair($set)
            );
        }
    }

    // Clean up.
    foreach ($sets as $k => $set)
    {
        if (false !== strpos($set, '('))
        {
            unset($sets[$k]);
        }
    }
    $sets = array_unique($sets);
    sort($sets);

    return $sets;
}

var_dump(expand_filenames('/(a|b)/var/(www|www2)/index.(htm|html|php|shtml)'));

Ben aradığınız düşünüyorum:

/ (([^ |] +) (| ([^ |] +)) +) /

Yinelenen bir kalıba | 'temelde, splitter koydu.

Ayrıca, kelimeler üçüncü şartının yerine 'değil Pars' ve 'değil boru' kadar yapılmalıdır.

Ayrıca, bu sorun için + * tercih. + 'en az bir "anlamına gelir. * 'sıfır ya da daha fazla "anlamına gelir.

Tam olarak ne soruyorsun, ama sadece ne sen (görmezden | s) listesini almak için ne alarak yanlış bir değişken içine koyarak ve ardından explode üzerinde ing | s ? (| Mevcut bir orada değilse 1 dahil) İşte size vardı, ancak birçok öğe bir dizi verecek.

Yapmanız hangi durumda dosyalardan birini vurmak kadar Belki hala soru almıyorum, ama benim varsayım dosya sistemi ile çalışan bir

$files = glob("$path/index.{htm,html,php,shtml}", GLOB_BRACE);

Edilen dizisi $ yolu ya da hiçbirinde uzantılarını eşleşen herhangi bir dosya içerir. Belirli bir uzantı için dosyaları eklemek gerekirse, can foreach uzantıları sıralı bir liste ile dizi üzerine, örneğin

foreach(array('htm','html','php','shtml') as $ext) {
    foreach($files as $file) {
        if(pathinfo($file, PATHINFO_EXTENSION) === $ext) {
            // do something
        }
    }
}

Edit: ve evet, glob birden küme parantezi olabilir.

Cevabı verilmiş, ama komik bir bulmaca ve ben sadece dayanamadı edilir

function expand_filenames2($str) {
    $r = array($str);
    $n = 0;
    while(preg_match('~(.*?) \( ( \w+ \| [\w|]+ ) \) (.*) ~x', $r[$n++], $m)) {
        foreach(explode('|', $m[2]) as $e)
            $r[] = $m[1] . $e . $m[3];
    }
    return array_slice($r, $n - 1);
}  



print_r(expand_filenames2('/(a|b)/var/(ignore)/(www|www2)/index.(htm|html|php|shtml)!'));

belki bu yüzden seviyorum biraz düzenli ifadeleri açıklar o kadar ;)