[Finder] Add double-star matching to Glob::toRegex()

This commit is contained in:
Nicolas Grekas 2017-02-08 23:46:33 +01:00
parent 2697ceecf7
commit 8b28afa0f6
6 changed files with 50 additions and 8 deletions

View File

@ -1,6 +1,11 @@
CHANGELOG
=========
3.3.0
-----
* added double-star matching to Glob::toRegex()
3.0.0
-----

View File

@ -54,16 +54,18 @@ class Glob
$sizeGlob = strlen($glob);
for ($i = 0; $i < $sizeGlob; ++$i) {
$car = $glob[$i];
if ($firstByte) {
if ($strictLeadingDot && '.' !== $car) {
$regex .= '(?=[^\.])';
}
$firstByte = false;
if ($firstByte && $strictLeadingDot && '.' !== $car) {
$regex .= '(?=[^\.])';
}
if ('/' === $car) {
$firstByte = true;
$firstByte = '/' === $car;
if ($firstByte && $strictWildcardSlash && isset($glob[$i + 3]) && '**/' === $glob[$i + 1].$glob[$i + 2].$glob[$i + 3]) {
$car = $strictLeadingDot ? '/((?=[^\.])[^/]+/)*' : '/([^/]+/)*';
$i += 3;
if ('/' === $delimiter) {
$car = str_replace('/', '\\/', $car);
}
}
if ($delimiter === $car || '.' === $car || '(' === $car || ')' === $car || '|' === $car || '+' === $car || '^' === $car || '$' === $car) {

View File

@ -11,6 +11,7 @@
namespace Symfony\Component\Finder\Tests;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\Glob;
class GlobTest extends \PHPUnit_Framework_TestCase
@ -22,4 +23,38 @@ class GlobTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('^\.[^/]*$', Glob::toRegex('.*', true, true, ''));
$this->assertEquals('/^\.[^/]*$/', Glob::toRegex('.*', true, true, '/'));
}
public function testGlobToRegexDoubleStarStrictDots()
{
$finder = new Finder();
$finder->ignoreDotFiles(false);
$regex = Glob::toRegex('/**/*.neon');
foreach ($finder->in(__DIR__) as $k => $v) {
$k = str_replace(DIRECTORY_SEPARATOR, '/', $k);
if (preg_match($regex, substr($k, strlen(__DIR__)))) {
$match[] = substr($k, 10 + strlen(__DIR__));
}
}
sort($match);
$this->assertSame(array('one/b/c.neon', 'one/b/d.neon'), $match);
}
public function testGlobToRegexDoubleStarNonStrictDots()
{
$finder = new Finder();
$finder->ignoreDotFiles(false);
$regex = Glob::toRegex('/**/*.neon', false);
foreach ($finder->in(__DIR__) as $k => $v) {
$k = str_replace(DIRECTORY_SEPARATOR, '/', $k);
if (preg_match($regex, substr($k, strlen(__DIR__)))) {
$match[] = substr($k, 10 + strlen(__DIR__));
}
}
sort($match);
$this->assertSame(array('.dot/b/c.neon', '.dot/b/d.neon', 'one/b/c.neon', 'one/b/d.neon'), $match);
}
}