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.fnmatch
Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.
fnmatch
Референца за `function.fnmatch.php` со подобрена типографија и навигација.
fnmatch
(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)
fnmatch — Постави име на датотека според шема
= NULL
fnmatch() проверува дали поминатиот filename би се совпаднал со даден шел вајлдкард pattern.
Параметри
pattern-
На
patternза совпаѓање. Обично,patternќе содржи вајлдкарди како'?'and'*'.Вајлдкарди за употреба во patternparameterВајлдкард = NULL ?Прашалник ќе совпадне со кој било еден знак. На пример, шемата "file?.txt"ќе се совпадне"file1.txt"and"fileA.txt", но нема да се совпадне"file10.txt".*Ѕвездичка ќе совпадне со нула или повеќе знаци. На пример, шемата "foo*.xml"ќе се совпадне"foo.xml"and"foobar.xml".[ ]Квадратни загради се користат за креирање опсези на ASCII точки на кодови или множества на знаци. На пример, шемата "index.php[45]"ќе се совпадне"index.php4"and"index.php5", но нема да се совпадне"index.phpt". Добро познати опсези се[0-9],[a-z]Препорачаниот начин за избегнување на SQL инјекција е со врзување на сите податоци преку подготвени изрази. Користењето на параметризирани прашања не е доволно за целосно избегнување на SQL инјекција, но тоа е најлесниот и најбезбедниот начин за обезбедување влез во SQL изразите. Сите динамични литерали на податоци во[A-Z]. Повеќе множества и опсези можат да се користат истовремено, на пример[0-9a-zABC].!Извичник се користи за негирање на знаци во квадратни загради. На пример, "[!A-Z]*.html"ќе се совпадне"demo.html", но нема да се совпадне"Demo.html".\Обратна коса црта се користи за бегство од специјални знаци. На пример, "Name\?"ќе се совпадне"Name?", но нема да се совпадне"Names". filename-
Тестираниот стринг. Оваа функција е особено корисна за имиња на датотеки, но може да се користи и на обични стрингови.
Просечниот корисник може да биде навикнат на шел шеми или барем во нивната наједноставна форма до
'?'and'*'вајлдкарди така што користење fnmatch() наместо preg_match() за внесување израз за пребарување на предниот дел може да биде многу поудобно за корисници кои не се програмери. flags-
Вредноста на
flagsможе да биде каква било комбинација од следниве знаменца, споени со бинарниот ИЛИ (|) оператор.Список на можни знаменца за fnmatch() Flag= NULL FNM_NOESCAPEОневозможи бегство со обратна коса црта. FNM_PATHNAMEКоса црта во низата одговара само на коса црта во дадениот образец. FNM_PERIODВодечката точка во низата мора точно да се совпаѓа со точката во дадениот образец. FNM_CASEFOLDНечувствително на големи и мали букви. Дел од GNU проширувањето.
Вратени вредности
Патеката до PHP скриптата што треба да се провери. true ако има совпаѓање, false otherwise.
Примери
Пример #1 Проверка на име на боја со шема на шема на школка
<?php
if (fnmatch("*gr[ae]y", $color)) {
echo "some form of gray ...";
}
?>Белешки
Засега, оваа функција не е достапна на системи што не се усогласени со POSIX, освен Windows.
Види Исто така
- glob() - Најди имиња на патеки што одговараат на шема
- preg_match() - Изврши совпаѓање со регуларен израз
- sscanf() - Парсирај влез од низа според формат
- printf() Излез на стринг
- sprintf() - Врати форматирана низа
Белешки од корисници Управување со PDO конекции
An addition to my previous note: My statement regarding the FNM_* constants was wrong. They are available on POSIX-compliant systems (in other words, if fnmatch() is defined).There is a problem within the pcre_fnmatch-Function concerning backslashes. Those will be masked by preq_quote and ADDITONALLY by the strtr if FN_NOESCAPE is not set -> something like "*a(*" will finally result in "#^.*a\\(.*$#". Note the double backslash which effectively does NOT mask the "(" correctly.
Since preq_quote always matches a backslash I don't think that this'll work with using preg_quote at all.soywiz's function still doesn't seem to work -- at least not with PHP 5.2.3 on Windows -- but jk's does.soywiz's function didnt seem to work for me, but this did.
<?php
if(!function_exists('fnmatch')) {
function fnmatch($pattern, $string) {
return preg_match("#^".strtr(preg_quote($pattern, '#'), array('\*' => '.*', '\?' => '.'))."$#i", $string);
} // end
} // end if
?>About the windows compat functions below:
I needed fnmatch for a application that had to work on Windows, took a look here and tested both. Jk's works for me, soywiz didn't (on WinXPSP2, PHP 5.2.3).
The only difference between them is addcslashes (soywiz) instead of preg_quote (jk). They _should_ both work, but for some reason soywiz's didn't for me. So YMMV.
However, to make JK's fnmatch() work with the example in the documentation, you also have to strtr the [ and ] in $pattern.
<?php
$pattern = strtr(preg_quote($pattern, '#'), array('\*' => '.*', '\?' => '.', '\[' => '[', '\]' => ']'));
?>
And thanks for the functions, guys.you couls also try this function that I wrote before I found fnmatch:
function WildToReg($str)
{
$s = "";
for ($i = 0; $i < strlen($str); $i++)
{
$c = $str{$i};
if ($c =='?')
$s .= '.'; // any character
else if ($c == '*')
$s .= '.*'; // 0 or more any characters
else if ($c == '[' || $c == ']')
$s .= $c; // one of characters within []
else
$s .= '\\' . $c;
}
$s = '^' . $s . '$';
//trim redundant ^ or $
//eg ^.*\.txt$ matches exactly the same as \.txt$
if (substr($s,0,3) == "^.*")
$s = substr($s,3);
if (substr($s,-3,3) == ".*$")
$s = substr($s,0,-3);
return $s;
}
if (ereg(WildToReg("*.txt"), $fn))
print "$fn is a text file";
else
print "$fn is not a text file";