Builds pattern search trie from pattern list(s).

@param array $patterns An array of hyphenation patterns.

@return Trie_Node The starting node of the trie.
974796
public static function build_trie( array $patterns ) {
		$trie = new Trie_Node();

		foreach ( $patterns as $key => $pattern ) {
			$node = $trie;

			foreach ( Strings::mb_str_split( $key ) as $char ) {
				$node = $node->get_node( $char );
			}

			\preg_match_all( '/([1-9])/S', $pattern, $offsets, PREG_OFFSET_CAPTURE );
			$node->offsets = $offsets[1];
		}

		return $trie;
	}
1239473
public function filterMatch($patterns)
    {
        $patterns = is_string($patterns) ? [$patterns] : $patterns;

        // String pattern is assumed to be path.
        foreach ($patterns as $key => $pattern) {
            if (is_string($pattern)) {
                $patterns[$key] = ['path' => $pattern];
            }
        }

        return $this->filter(function ($route) use ($patterns) {
            // If any of patterns matches - route passes.
            foreach ($patterns as $pattern) {
                if ($this->isRouteMatchesPattern($route, $pattern)) {
                    return true;
                }
            }

            // If all patterns don't match - route is filtered out.
            return false;
        });
    }
349365
public static function createPattern($pattern)
    {
        $numVer = '([0-9]+|x|\*)';
        $numVer2 = '('.$numVer.'\.'.$numVer.')';
        $numVer3 = '('.$numVer.'\.'.$numVer.'\.'.$numVer.')';

        return '/^'.'('.$numVer.'|'.$numVer2.'|'.$numVer3.')'.$pattern.'/';
    }
1054070
protected function expandPatterns(array $patterns, $search, array $replacements)
    {
        if ($replacements === []) {
            return $patterns;
        }
        $patternsWithReplacements = [];
        foreach ($patterns as $pattern) {
            foreach ($replacements as $replacement) {
                $patternsWithReplacements[] = Files::getUnixStylePath(str_replace($search, $replacement, $pattern));
            }
        }

        return $patternsWithReplacements;
    }
57980
protected function mergeWithLocalPatterns(array $patterns) {
        $mergedPatterns = $this->patterns;

        foreach ($patterns as $name => $pattern) {
            array_unshift($mergedPatterns, $this->createPattern($name, $pattern));
            array_unshift($mergedPatterns, $this->createPattern($name, $pattern, true));
        }

        return $mergedPatterns;
    }
715943
private function expandClasses(array $patterns, array $classes)
    {
        $expanded = [];

        // Explicit classes declared in the patterns are returned directly
        foreach ($patterns as $key => $pattern) {
            if ('\\' !== substr($pattern, -1) && false === strpos($pattern, '*')) {
                unset($patterns[$key]);
                $expanded[] = ltrim($pattern, '\\');
            }
        }

        // Match patterns with the classes list
        $regexps = $this->patternsToRegexps($patterns);

        foreach ($classes as $class) {
            $class = ltrim($class, '\\');

            if ($this->matchAnyRegexps($class, $regexps)) {
                $expanded[] = $class;
            }
        }

        return array_unique($expanded);
    }
887964
public function filterExcept($patterns = [])
    {
        if (empty($patterns)) {
            return $this;
        }

        $toExclude = $this->filterMatch($patterns)->keys()->toArray();

        return $this->except($toExclude);
    }
646134
public function convertSplittersToRegexPattern( $splitters ) {
	    $regex_parts = array();
	    foreach ( $splitters as $part ) {
		    $part = preg_quote( $part );

		    switch ( $part ) {
			    case "\r\n":
				    $part = '\r\n';
				    break;
			    case "\t":
				    $part = '\t';
				    break;
			    case "\n":
				    $part = '\n';
				    break;
			    case " ":
				    $part = '\s';
				    break;
			    case "/":
				    $part = "\/";
				    break;
			    case "/\*":
				    $part = "\/\*";
				    break;
			    case "\*/":
				    $part = "\*\/";
				    break;
		    }

		    $regex_parts[] = $part;
	    }

	    $pattern = implode( '|', $regex_parts );

	    return '/(' . $pattern . ')/';
    }
1152343
protected function buildBuilders($pattern, array $matches)
    {
        $result = [
            'pattern' => $pattern,
            'segments' => []
        ];

        foreach ($matches as $match) {
            list($key,) = $this->splitSegment($match[3]);
            $result['pattern'] = str_replace($match[0], '{' . $key . '}', $result['pattern']);
            $result['segments']['{' . $key . '}'] = '{value}' . $match[4] . (isset($match[7]) ? $match[7] : '');
        }

        return $result;
    }
650489
public function parsePattern($pattern)
    {
        $withoutClosing = rtrim($pattern, "]");
        $closingNumber  = strlen($pattern) - strlen($withoutClosing);

        $segments = preg_split("~" . self::DYNAMIC_REGEX . "(*SKIP)(*F)|\[~x", $withoutClosing);
        $this->parseSegments($segments, $closingNumber, $withoutClosing);

        return $this->buildSegments($segments);
    }
1001996
protected function createPatternsForStrings(array $strings) {
        $patterns = [];

        foreach ($strings as $string) {
            $string = preg_quote($string);

            // dist
            $patterns[] = s('#^(%s)$#', $string);
            // dist.
            $patterns[] = s('#^(%s)[._+:-]+#', $string);
            // .dist
            $patterns[] = s('#[._+:-]+(%s)$#', $string);
            // .dist.
            $patterns[] = s('#[._+:-]+(%s)[._+:-]+#', $string);
        }

        return $patterns;
    }
669223
protected function pregGrepRecursive($pattern, $haystack)
    {
        $matches = [];
        
        foreach ($haystack as $key => $item) {
            if (is_array($item)) {
                $sub_matches = $this->pregGrepRecursive($pattern, $item);
                
                if ($sub_matches) {
                    $matches[$key] = $sub_matches;
                }
            } elseif (preg_match($pattern, $item)) {
                $matches[$key] = $item;
            }
        }
        
        return $matches;
    }
890617
public FulltextMatch setPatterns(
                    final Collection<String> patterns
                    )
    {
        if (patterns == null  ||  patterns.size() == 0) {
            clearPatterns();
            return this;
        }

        synchronized (patterns) {
            for (String  pattern : patterns) {
                if (pattern == null  ||  pattern.length() == 0) {
                    throw new IllegalArgumentException( "null element" );
                }
            }

            clearPatterns();
            for (String  pattern : patterns) {
                addPattern( pattern );
            }
        }

        return this;
    }
1133598
protected function convertPatternStep2($prefix, $searchPattern, $pattern)
    {
        if ('.*' === $searchPattern) {
            $this->doAddPattern($prefix.'**/.*');
        } elseif ('**' === $searchPattern) {
            $this->finder->path('/.*/');
            $this->finder->notPath('/^\..*(?!\/)/');
        } elseif (preg_match('/\/\*$|\/\*\*$/', $pattern, $matches)) {
            $this->doAddPattern(substr($pattern, 0, \strlen($pattern) - \strlen($matches[0])));
        }
    }
909404
private static function firstWildcardInPattern($pattern)
    {
        $wildcards = ['*', '?', '[', '\\'];
        $wildcardSearch = function ($carry, $item) use ($pattern) {
            $position = strpos($pattern, $item);

            if ($position === false) {
                return $carry === false ? $position : $carry;
            }

            return $carry === false ? $position : min($carry, $position);
        };

        return array_reduce($wildcards, $wildcardSearch, false);
    }
585051
private function findSourcesInPattern(string $pattern): array
  {
    $sources = [];

    $directory = new RecursiveDirectoryIterator(self::getLeadingDir($pattern));
    $directory->setFlags(RecursiveDirectoryIterator::FOLLOW_SYMLINKS);
    $files = new RecursiveIteratorIterator($directory);
    foreach ($files as $fullPath => $file)
    {
      // If the file is a source file with stored routine add it to my sources.
      if ($file->isFile() && SelectorHelper::matchPath($pattern, $fullPath))
      {
        $sources[] = $fullPath;
      }
    }

    return $sources;
  }
502523
public function names(array $patterns): self
    {
        $filter = new Iterator\FilenameFilterIterator($this->getIterator(), $patterns, []);

        return new self(iterator_to_array($filter));
    }