Use the glob function provided by the system.

@param  string  $pattern
@param  int     $flags
@return array
510677
protected static function systemGlob($pattern, $flags)
    {
        ErrorStack::handleError();
        $res = glob($pattern, $flags);
        $err = ErrorStack::handleDone();
        if ($res === false)
            throw new \RuntimeException("glob('{$pattern}', {$flags}) failed", 0, $err);

        return $res;
    }
1230763
public function setInclude(string $pattern, string $flags = null): self
    {
        if (null === $flags) {
            return $this->setParam('include', $pattern);
        }

        return $this->setParam('include', [
            'pattern' => $pattern,
            'flags' => $flags,
        ]);
    }
379185
public function filter($pattern, $subject, $limit = -1, $flags = 0)
    {
        return $this->sandbox->run('preg_filter', func_get_args(), $this->throw);
    }
1018146
protected static function transform(Pattern $pattern) {
        $result = [];
        $groups = [[$pattern]];

        while ($groups) {
            $children = array_shift($groups);
            $hasBranchPattern = false;
            foreach ($children as $c) {
                if ($c instanceof BranchPattern) {
                    $hasBranchPattern = true;
                    break;
                }
            }
            if ($hasBranchPattern) {
                /** @var BranchPattern $child */
                $child = null;
                foreach ($children as $key => $currentChild) {
                    if ($currentChild instanceof BranchPattern) {
                        $child = $currentChild;
                        unset($children[$key]);
                        break;
                    }
                }
                if ($child instanceof Either) {
                    foreach ($child->children as $c) {
                        $groups[] = array_merge([$c], $children);
                    }
                }
                else if ($child instanceof OneOrMore) {
                    $groups[] = array_merge($child->children, $child->children, $children);
                }
                else {
                    $groups[] = array_merge($child->children, $children);
                }
            }
            else {
                $result[] = $children;
            }
        }

        $rs = [];
        foreach ($result as $e) {
            $rs[] = new Required($e);
        }
        return new Either($rs);
    }
1203295
protected function processPattern(array $patterns)/*# : array */
    {
        $result = [];
        foreach ($patterns as $pat) {
            $part = explode('/', $pat);
            $addr = ip2long($part[0]);
            $mask = isset($part[1]) ? ((int) $part[1]) : 32;

            // fix
            $mask = $this->getMask($mask);
            $addr = $addr & $mask;

            $result[] = [$addr, $mask];
        }
        return $result;
    }
1332896
protected static function fallbackGlob($pattern, $flags)
    {
        if (! $flags & self::GLOB_BRACE) {
            return static::systemGlob($pattern, $flags);
        }
        $flags &= ~self::GLOB_BRACE;
        $length = strlen($pattern);
        $paths  = [];
        if ($flags & self::GLOB_NOESCAPE) {
            $begin = strpos($pattern, '{');
        } else {
            $begin = 0;
            while (true) {
                if ($begin === $length) {
                    $begin = false;
                    break;
                } elseif ($pattern[$begin] === '\\' && ($begin + 1) < $length) {
                    $begin++;
                } elseif ($pattern[$begin] === '{') {
                    break;
                }
                $begin++;
            }
        }
        if ($begin === false) {
            return static::systemGlob($pattern, $flags);
        }
        $next = static::nextBraceSub($pattern, $begin + 1, $flags);
        if ($next === null) {
            return static::systemGlob($pattern, $flags);
        }
        $rest = $next;
        while ($pattern[$rest] !== '}') {
            $rest = static::nextBraceSub($pattern, $rest + 1, $flags);
            if ($rest === null) {
                return static::systemGlob($pattern, $flags);
            }
        }
        $p = $begin + 1;
        while (true) {
            $subPattern = substr($pattern, 0, $begin)
                . substr($pattern, $p, $next - $p)
                . substr($pattern, $rest + 1);
            $result = static::fallbackGlob($subPattern, $flags | self::GLOB_BRACE);
            if ($result) {
                $paths = array_merge($paths, $result);
            }
            if ($pattern[$next] === '}') {
                break;
            }
            $p    = $next + 1;
            $next = static::nextBraceSub($pattern, $p, $flags);
        }
        return array_unique($paths);
    }
1081855
private static function PrepareRegexPattern( $pattern, $flagString )
	{

		// Check the pattern does not include a back-reference in a character class
		$result = preg_match( "/\[.*?\\\\\d+.*?\]/", $pattern );
		if ( $result )
		{
			throw XPath2Exception::withErrorCodeAndParam( "FORX0002", Resources::InvalidRegularExpr, "$pattern/$flagString" );
		}

		// If one of the flags is x then need to remove whitespace not in character classes
		// PCRE will not remove escaped spaces when the x flag is used but XPath expects them to be removed
		if ( strpos( $flagString, "x" ) !== false )
		{
			$results = preg_match_all( "/((?<expr>[^[]*)(?<chars>\[.*?\])?)/", $pattern, $matches );
			for ( $i = 0; $i < $results; $i++ )
			{
				$match = $matches['expr'][ $i ];
				if ( empty( $match) ) continue;
				$result = preg_replace( "/((?![\r\n])\s)+/", "", $match );
				if ( $match == $result ) continue;
				$pattern = str_replace( $match, $result, $pattern );
			}
		}

		// If there is a back-reference need to add an empty comment to separate the
		// back-reference number from any following digit(s) and repeat for all back-references
		// $groups = substr_count( $pattern, "(" );
		// This pattern counts the parentheses that are not escaped by just one backslash (two is OK)
		$groups = preg_match_all( '/\\\\\\\\\(|\((?<!\\\\\()/', $pattern );
		if ( $groups )
		{
			// Get a list of all the back reference numbers
			$result = preg_match_all( "/\\\\(\d(\d?))*/", $pattern, $matches );
			if ( $result )
			{
				// $result2 = preg_match_all( "/\((([^()]+)|(?R))*\)/", $pattern, $parens );

				// Grab the valid values
				$values = array();
				foreach ( array_filter( $matches[1] ) as $key => $match )
				{
					$potentialValues = array();
					while ( strlen( $match ) > 0 )
					{
						$potentialValues[] = $match;
						$match = substr( $match, 0, strlen( $match ) - 1 );
					}

					sort( $potentialValues );
					$error = false;
					while ( count( $potentialValues ) )
					{
						$value = array_pop( $potentialValues );

						// Find the match(es) in the string and count the number of opening parentheses until that point
						$pos = strpos( $pattern, $value );

						// $matchgroupsOpen = substr_count( $pattern, "(", 0, $pos );
						// This horrible list of backslashes occurs because the regex escape char is \ and the same for PHP.
						// So every real backslash has to be quadrupled. Here's what the regex will look like outside PHP
						// 	/\\\\\(|\((?<!\\\()/
						$matchgroupsOpen = preg_match_all( '/\\\\\\\\\(|\((?<!\\\\\()/', substr( $pattern, 0, $pos ) );

						// If there are no groups throw an exception
						$error = ! $matchgroupsOpen || $matchgroupsOpen < $value;

						if ( ! $error )
						{
							// $matchgroupsClosed = substr_count( $pattern, ")", 0, $pos );
							$matchgroupsClosed = preg_match_all( '/\\\\\\\\\)|\)(?<!\\\\\))/', substr( $pattern, 0, $pos ) );

							// If reference is in a capture group its an error
							$error = ! $matchgroupsClosed || $matchgroupsClosed != $matchgroupsOpen || $matchgroupsClosed < $value;

							if ( $error ) continue;
							// This is the longest number
							$values[] = $value;
							break;
						}
					}

					if ( $error )
					{
						throw XPath2Exception::withErrorCode( "FORX0002", Resources::FORX0002 );
					}
				}

				// Make sure the back-reference numbers are valid given the list of capture groups available
				$validValues = array_intersect( $values, range( 1, $groups ) );

				// Sort them in descending order so the longest number is handled first.
				// This way \1 and \11 are handled correctly.
				// BMS Not sure this is necessary.
				rsort( $validValues );
				foreach ( $validValues as $value )
				{
					// Replace the number but only if the number is not already followed by an empty comment
					$pattern = preg_replace( "/\\\\($value)(?!\d?\(\?\#\))/", "\\\\$1(?#)", $pattern );
				}
			}
		}

		// Check to see if there are any character classes that specify character subtraction
		// If so, convert to a negative lookahead
		$results = preg_match_all( "/\[(?<chars>((.*)?(.-.))+)-(?<sub>\[(.*|.*?(.-.))+\])\]/", $pattern, $matches );
		if ( $results )
		{
			for ( $i = 0; $i < $results; $i++ )
			{
				$chars = $matches['chars'][ $i ];
				$sub = $matches['sub'][ $i ];
				$x = "(?!$sub)[$chars]";

				$pattern = str_replace( $matches[ $i ], $x, $pattern );
			}
		}

		// Replace common unicode character classes
		$pattern = str_replace( "{IsBasic", "{", $pattern );

		return $pattern;
	}
882689
public function whereRegex($expr, $regex, $flags = '')
    {
        $key = $expr;
        $this->_conditions[] = $expr . ' REGEXP ' . (strpos($flags, 'i') !== false ? '' : 'BINARY ') . ':' . $key;
        $this->_bind[$key] = $regex;

        return $this;
    }
340419
public static function glob(string $path, $pattern = null, $strategy = self::SCAN_DFS): array
    {
        if (! is_dir($path) || ! $pattern) {
            throw new \InvalidArgumentException('Invalid $path or $pattern for DirHelper::glob');
        }

        $files = self::scan($path, $strategy);
        $result = [];
        foreach ($files as $file) {
            if (false === self::matchPattern($pattern, $file)) {
                continue;
            }
            $result[] = $file;
        }
        return $result;
    }
193512
protected function parsePlaceholders($pattern)
    {
        $params = [];
        $parser = $this->parser;

        preg_match_all("~" . $parser::DYNAMIC_REGEX . "~x", $pattern, $matches, PREG_SET_ORDER);

        foreach ((array) $matches as $key => $match) {
            $pattern = str_replace($match[0], isset($match[2]) ? "({$match[2]})" : "([^/]+)", $pattern);
            $params[$key] = $match[1];
        }

        return [$pattern, $params];
    }
1361698
public static function searchFile($root, $pattern = '*', $flags = 0)
    {
        $dirs = self::listDirs($root);
        array_unshift($dirs, $root);
        
        $foundFiles = [];
        
        if ($pattern instanceof \Closure) {
            $closure = $pattern;
            $pattern = '*';
        } else {
            $closure = null;
        }
        
        foreach ($dirs as $dir) {
            $filePatt = $dir . '/' . $pattern;
            $files = glob($filePatt, $flags);
            
            if ($closure) {
                foreach ($files as $file) {
                    if ($closure($file)) {
                        $foundFiles[] = $file;
                    }
                }
            } else {
                if ($files) {
                    $foundFiles = array_merge($foundFiles, $files);
                }
            }
        }
        
        return $foundFiles;
    }
396337
protected function findFilesInCacheDir($pattern)
    {
        $finder = new Finder();
        
        return $finder
            ->name($pattern)
            ->in($this->getCacheDir())
        ;
    }
364263
public static function filterArrayValuesWithPattern(array $values, $pattern)
    {
        return array_values(
            array_filter(
                array_map(function ($key) use ($pattern) {
                    if ((bool) preg_match('/'.$pattern.'/', $key)) {
                        return $key;
                    }
                }, $values)
            )
        );
    }
452610
public static function glob($pattern, $flags = 0, $forceFallback = false)
    {
        if (!defined('GLOB_BRACE') || $forceFallback) {
            return static::fallbackGlob($pattern, $flags);
        }

        return static::systemGlob($pattern, $flags);
    }
850574
public function matching ($pattern, &$matches = [], $flags = 0, $offset = 0, $start = 0, $end = null) {
		if (is_null($end)) {
			$end = $this->_length;
		}
		return static::Match($pattern, static::Substring($this->_string, $start, $end), $matches, $flags, $offset);
	}
538453
protected function rglob($pattern = '*', $flags = 0, $path = '')
    {
        $paths = glob($path . '*', GLOB_MARK | GLOB_ONLYDIR | GLOB_NOSORT);
        $files = glob($path . $pattern, $flags);
        foreach ($paths as $path) {
            $files = array_merge(
                $files,
                $this->rglob($pattern, $flags, $path)
            );
        }

        return $files;
    }
1224161
protected function _globRecursive($pattern, $flags = 0) {
		$files = glob($pattern, $flags);
		foreach (glob(dirname($pattern).'/*', GLOB_NOSORT) as $dir) {
			$files = array_merge($files, $this->_globRecursive($dir.'/'.basename($pattern), $flags));
		}

		return $files;
	}