Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Строим регулярку по маске файла


Автор: ksnk 8.11.2015, 12:17
Маска файла - простой и, что самое главное, юзеропонятный способ указать группу файлов. Значительно более юзеропонятный, чем регулярное выражение. При загрузке файлов на сайт, анализе почтовых логов и так далее, возникает желание элегантно отделить нужные файлы от ненужных.

Итого - функция, которая преобразует маску в регулярку
Код

    /**
     * convert simple DOS-like mask with * and ? into regular expression
     * so
     *   * - all files - there is a difference with a rest "select by mask"
     *   *.xml - all files with xlm extension
     *   *.jpg|*.jpeg|*.png - some pictures
     *   hello*world?.txt - helloworld1.txt,helloXXXworld2.txt, and so on
     *
     * @param $mask - simple mask
     * @param bool $last - mask end with last simbol
     * @param bool $isfilemask
     * @return string
     */
    function masktoreg($mask, $last = true, $isfilemask = true)
    {
        if (!empty($mask) && $mask{0} == '/') return $mask; // это уже регулярка
        if($isfilemask){
            $star='[^:/\\\\\\\\]';//
            $mask=explode('|',$mask);
        } else {
            $star='.';//
            $mask=array($mask);
        }
        /* so create mask */
        $regs = array(
            '~\[~' => '@@0@@',
            '~\]~' => '@@1@@',
            '~[\\\\/]~' => '@@2@@',
            '/\*\*+/' => '@@3@@',
            '/\./' => '\.',
            '/\|/' => '\|',
            '/\*/' => $star . '*',
            '/\?/' => $star,
            '/#/' => '\#',
            '/@@3@@/' => '.*',
            '/@@2@@/' => '[\/\\\\\\\\]',
            '/@@1@@/' => '\]',
            '/@@0@@/' => '\[',
        );
        $r=array();
        foreach($mask as $m)
            $r[]=preg_replace(
                    array_keys($regs), array_values($regs), $m
                ) . ($last ? '$' : '');
        return '#' . implode('|',$r). '#iu';
    }

 
Функция несколько сложнее, чем могла бы быть, так как я использую ее и для поиска в текстовых строках (почтовые subj, from, to,...)

Функция регистронезависима, не делает разницы между названиями файлов windows и unix, слеши и обратные слеши взаимозаменяемы.
Символ ** - означает все символы, в то время как * - все, за исключением слеша и `: `.

Может кому понадобится.

http://ideone.com/29isgO

Автор: _zorn_ 8.11.2015, 16:04
Цитата
if (!empty($mask) && $mask{0} == '/') return $mask; // это уже регулярка

А хрен тебе, я регулярки оборачиваю в решетки чтобы не городить забор smile
Если не знал, в пхп регулярка заканчивается на то же на что и начинается...
А еще модификаторы...

Автор: ksnk 8.11.2015, 16:20
_zorn_, маски берутся из конфига. Как-то надо же дать возможность продвинутому юзеру указать более точный критерий, чем маска.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)