note 100207 modified in function.fnmatch by danbrown

From: Date: Fri, 01 Oct 2010 11:59:53 +0000
Subject: note 100207 modified in function.fnmatch by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-172869@lists.php.net to get a copy of this message
Here's a definitive solution, which supports negative character classes and the four documented flags. <?php if (!function_exists('fnmatch')) { define('FNM_PATHNAME', 1); define('FNM_NOESCAPE', 2); define('FNM_PERIOD', 4); define('FNM_CASEFOLD', 16); function fnmatch($pattern, $string, $flags = 0) { return pcre_fnmatch($pattern, $string, $flags); } } function pcre_fnmatch($pattern, $string, $flags = 0) { $modifiers = null; $transforms = array( '\*' => '.*', '\?' => '.', '\[\!' => '[^', '\[' => '[', '\]' => ']', '\.' => '\.', '\\' => '\\\\' ); // Forward slash in string must be in pattern: if ($flags & FNM_PATHNAME) { $transforms['\*'] = '[^/]*'; } // Back slash should not be escaped: if ($flags & FNM_NOESCAPE) { unset($transforms['\\']); } // Perform case insensitive match: if ($flags & FNM_CASEFOLD) { $modifiers .= 'i'; } // Period at start must be the same as pattern: if ($flags & FNM_PERIOD) { if (strpos($string, '.') === 0 && strpos($pattern, '.') !== 0) return false; } $pattern = '#^' . strtr(preg_quote($pattern, '#'), $transforms) . '$#' . $modifiers; return (boolean)preg_match($pattern, $string); } ?> This probably needs further testing, but it seems to function identically to the native fnmatch implementation. --was-- The code below is not really useful, here is a better implementation with support for the four documented flags. <?php if (!function_exists('fnmatch')) { define('FNM_PATHNAME', 1); define('FNM_NOESCAPE', 2); define('FNM_PERIOD', 4); define('FNM_CASEFOLD', 16); function fnmatch($pattern, $string, $flags = 0) { return pcre_fnmatch($pattern, $string, $flags); } } function pcre_fnmatch($pattern, $string, $flags = 0) { $modifiers = null; $transforms = array( '\*' => '.*', '\?' => '.', '\[\!' => '[^', '\[' => '[', '\]' => ']', '\.' => '\.', '\\' => '\\\\' ); // Forward slash in string must be in pattern: if ($flags & FNM_PATHNAME) { $transforms['\*'] = '[^/]*'; } // Back slash should not be escaped: if ($flags & FNM_NOESCAPE) { unset($transforms['\\']); } // Perform case insensitive match: if ($flags & FNM_CASEFOLD) { $modifiers .= 'i'; } // Period at start must be the same as pattern: if ($flags & FNM_PERIOD) { if (strpos($string, '.') === 0 && strpos($pattern, '.') !== 0) return false; } $pattern = '#^' . strtr(preg_quote($pattern, '#'), $transforms) . '$#' . $modifiers; return (boolean)preg_match($pattern, $string); } ?> This probably needs further testing, but it seems to function identically to the native fnmatch implementation. http://php.net/manual/en/function.fnmatch.php

« previous php.notes (#172869) next »