A preg_replace helper to remove {{%PRAGMA}} tags and enable requested pragma.

@access protected
@param mixed $matches
@return void
@throws MustacheException unknown pragma
774065
protected function _renderPragma($matches) {
		$pragma         = $matches[0];
		$pragma_name    = $matches['pragma_name'];
		$options_string = $matches['options_string'];

		if (!in_array($pragma_name, $this->_pragmasImplemented)) {
			if ($this->_throwsException(MustacheException::UNKNOWN_PRAGMA)) {
				throw new MustacheException('Unknown pragma: ' . $pragma_name, MustacheException::UNKNOWN_PRAGMA);
			} else {
				return '';
			}
		}

		$options = array();
		foreach (explode(' ', trim($options_string)) as $o) {
			if ($p = trim($o)) {
				$p = explode('=', $p);
				$options[$p[0]] = $p[1];
			}
		}

		if (empty($options)) {
			$this->_localPragmas[$pragma_name] = true;
		} else {
			$this->_localPragmas[$pragma_name] = $options;
		}

		return '';
	}
442524
protected function fixMatches($matches)/*# : array */
    {
        $this->removeNumericAndEmpty($matches);

        // get route key/name
        $routeName = array_keys($matches)[0];
        $len = strlen($routeName);
        $res = [];
        foreach ($matches as $key => $val) {
            if ($key != $routeName) {
                $res[substr($key, 0, -$len)] = $val;
            }
        }

        $this->debug(Message::get(
            Message::RTE_PARSER_MATCH,
            $routeName,
            $this->regex[$routeName]
        ));

        return [$routeName, $res];
    }
15463
protected function replaceColors($text, $tag, $match, ColorStyle $style)
    {
        $replace = $this->noColors
            ? $match
            : "\033[" . $style . "m" . $match . "\033[0m";

        return str_replace('<' . $tag . '>' . $match . '</' . $tag . '>', $replace, $text);
    }
1156999
protected function replaceCallback($matches)
    {
        if (!empty($matches['beforeSkip']) && !empty($matches['afterSkip'])) {
            return trim($matches[0], '{!} ');
        }
        // check: count quotes does not parity
        if (!NumericHelper::isParity(mb_substr_count($matches[0], '`', 'UTF-8'))) {
            return $matches[0];
        }
        $matches[0] = preg_replace_callback(
            '/
                \\s*(?P<sugar> (?!`)\*(?!`) | (?!`)\*\*(?!`) | (?!`)\/(?!`) | (?!`)\%(?!`) |
                \\s+(?!`)mod(?!`)\\s+ | (?!`)\+(?!`) | (?!`)\-(?!`) | (?!`)\|(?!`) | (?!`)\&(?!`) |
                (?!`)\^(?!`) | (?!`)\>\>(?!`) | (?!`)\<\<(?!`) |
                (?!`)\|\|(?!`) | (?!`)\&\&(?!`) | \\s+(?!`)' . $this->_getInlineConditionNames() . '(?!`)\\s+ |`\\s+\?\\s+|`\\s+\:\\s+)\\s*`
            /x',
            [$this, 'replaceSugar'],
            $matches[0]);
        // replace `=` tpl mnemonics
        $matches[0] = preg_replace('/`([\!\<\>]?)[\=]+`/', '`$1&#61;`', $matches[0]);
        // replace `text` to ““text””
        $matches[0] = preg_replace(['/=\\s*\`/', '/\`/'], ['=““', '””'], $matches[0]);
        // replacement of internal recursion on {{{...}}}
        $i = 0;
        $dataRecursive = [];
        $matches[0] = preg_replace_callback(
            '/\“\“(?:[^\“\”]++|(?R))*\”\”/iu',
            function ($value) use (&$dataRecursive, &$i) {
                $key = '{{{' . $i . '}}}';
                $value = current($value);
                $dataRecursive[$key] = $value;
                $i++;

                return $key;
            },
            $matches[0]
        );
        // Search params is variable of template
        $params = $this->_searchParams($matches[0], $dataRecursive);
        // Search of filters (modifiers)
        $filters = $this->_searchFilters($matches[0], $dataRecursive);
        $matches['name'] = trim($matches['name']);
        $params = Serialize::unserializeRecursive($params);
        // returns cache
        list($cacheKey, $cacheExpire, $cacheTags) = $this->calculateCacheParams($params);
        if (($resultCache = $this->getCacheContent($cacheKey)) !== false) {
            return $resultCache;
        }
        $filters = Serialize::unserializeRecursive($filters);
        $sanitize = $this->sanitize;
        if (isset($params['sanitize'])) {
            $sanitize = $params['sanitize'];
        } elseif(!empty($matches['sanitizeDisable'])) {
            $sanitize = self::SANITIZE_DISABLE;
        }

        // chunk
        if ($matches['type'] === '$') {
            $result = $this->getChunk($matches['name'], $params);
            // alias
        } elseif ($matches['type'] === '@@') {
            $result = Alias::getAlias("@{$matches['name']}");
            // placeholder
        } elseif ($matches['type'] === '+') {
            $result = $this->getPlaceholder($matches['name'], $sanitize);
            // constant
        } elseif ($matches['type'] === '++') {
            $result = $this->getConst($matches['name'], $sanitize);
            // extension
        } elseif ($matches['type'] === '#') {
            $result =
                $this->getExtension($matches['name'], $params, $sanitize);
            //  i18n
        } elseif ($matches['type'] === '%') {
            $result = $this->_calculateI18N(
                $matches['name'],
                Helper::getValue($params['placeholders'], []),
                Helper::getValue($params['locale']),
                Helper::getValue($params['category'])
            );
            // link
        } elseif ($matches['type'] === '~') {
            $result = $this->_calculateLink($matches['name'], $params);
            // snippet
        } elseif (empty($matches['type'])) {
            $result = $this->getSnippet($matches['name'], $params, $sanitize);
        } else {
            return $matches[0];
        }
        // make a filter
        if (!empty($filters)) {
            $result = $this->makeFilter($result, $filters);
        }
        if ($this->autoSerialize) {
            if (is_array($result) || (is_object($result) && !$result instanceof \Closure)) {
                $result = @serialize($result);
            }
        }
        if (!is_scalar($result) && !empty($result)) {
            throw new TemplateException('Wrong type is var: ' . Json::encode($result));
        }
        // sets a content to cache
        $this->setCacheContent(
            $cacheKey,
            $result,
            $cacheExpire,
            $cacheTags ?: []
        );

        return $result;
    }
616025
protected function _replaceParamsCallback($matches)
    {
        $key   = substr($matches[0], 1);
        $value = $this->_parameters[$key];

        if(!$value instanceof KDatabaseQuerySelect) {
            $value = is_object($value) ? (string) $value : $value;
            $replacement = $this->getAdapter()->quoteValue($value);
        }
        else $replacement = '('.$value.')';

        return is_array($value) ? '('.$replacement.')' : $replacement;
    }
79386
protected function processNoConvert(string &$content): void
    {
        $pattern = '/{!}(' . preg_quote($this->startTag) . '.+?' . preg_quote($this->endTag) . ')/s';
        $content = preg_replace($pattern, '\1', $content);
    }
781875
private function findPattern($matches) {
        switch ($matches[1]) {
            case ':num':
                $replacement = '([0-9]';
                break;
            case ':alpha':
                $replacement = '([a-zA-Z]';
                break;
            case ':any':
                $replacement = '([^\/]';
                break;
        }


        if (isset($matches[3]) && is_numeric($matches[3])) {
            if (isset($matches[4]) && $matches[4] == '?') {
                $replacement .= '{0,' . $matches[3] . '})';
            } else {
                $replacement .= '{' . $matches[3] . '})';
            }
        } else {
            if (isset($matches[4]) && $matches[4] == '?') {
                $replacement .= '*)';
            } else {
                $replacement .= '+)';
            }
        }

        return $replacement;
    }
1154031
public static function html_tag_callback($matches)
    {
        // It might be an ending of a comment, ignore (#6464)
        if (substr($matches[3], -2) == '--') {
            $matches[0] = '';
            return implode('', $matches);
        }

        $tagname = $matches[2];
        $tagname = preg_replace(array(
            '/:.*$/',                // Microsoft's Smart Tags <st1:xxxx>
            '/[^a-z0-9_\[\]\!?-]/i', // forbidden characters
        ), '', $tagname);

        // fix invalid closing tags - remove any attributes (#1489446)
        if ($matches[1] == '</') {
            $matches[3] = '';
        }

        return $matches[1] . $tagname . $matches[3];
    }
881859
public function deleteMatchingNoneOfTags(array $tags)
    {
        $this->collection->batchDelete(function (\Sokil\Mongo\Expression $e) use ($tags) {
            return $e->whereNoneOf(Cache::FIELD_NAME_TAGS, $tags);
        });
        
        return $this;
    }
556111
public function replaceTags($str, $tags)
    {
        return preg_replace_callback(
            '/\\{([^{}]+)\}/',
            function ($matches) use ($tags) {
                return array_key_exists($matches[1], $tags)
                ? $tags[$matches[1]]
                : '';
            },
            $str
        );
    }
398233
private static function htmlAttrMatcher($matches) {

        $chr = $matches[0];
        $ord = ord($chr);

        //The following replaces characters undefined in HTML with the hex entity for the Unicode replacement character.
        if(($ord <= 0x1f && $chr != "\t" && $chr != "\n" && $chr != "\r") || ($ord >= 0x7f && $ord <= 0x9f)) {
            return '&#xFFFD;';
        }

        if(strlen($chr) > 1) {
            $chr = static :: convert($chr, 'UTF-8', 'UTF-32BE');
        }

        $hex = bin2hex($chr);
        $ord = hexdec($hex);

        $entities = [

	        34 => 'quot', //Quotation mark
	        38 => 'amp',  //Ampersand
	        60 => 'lt',   //Less-than sign
	        62 => 'gt',   //Greater-than sign
	    ];

        if(true === isset($entities[$ord])) {
            return '&' . $entities[$ord] . ';';
        }

        if($ord > 255) {
            return sprintf('&#x%04X;', $ord);
        }

        return sprintf('&#x%02X;', $ord);
    }
1155871
protected function _encodeCallback(array $matches) {
        $cacheSize = count($this->_cache);
        $this->_cache[$cacheSize] = $matches[2];

        return '[code' . $matches[1] . ']$$CODE' . $cacheSize . '$$[/code]';
    }
115008
private function restoreProtectedHtml($matches): string
    {
        \preg_match('/.*"(?<id>\d*)"/', $matches['attributes'], $matchesInner);

        $html = '';
        if (isset($this->protectedChildNodes[$matchesInner['id']])) {
            $html .= $this->protectedChildNodes[$matchesInner['id']];
        }

        return $html;
    }
628753
protected function _sanitize_naughty_html($matches) {
		// encode opening brace
		$str = '&lt;' . $matches[1] . $matches[2] . $matches[3];
		
		// encode captured opening or closing brace to prevent recursive vectors
		$str .= str_replace(array('>', '<'), array('&gt;', '&lt;'), $matches[4]);
		
		return $str;
	}
336747
function html_entity_replace($matches)
    {
        if ($matches[2])
        {
            return self::chr_utf8(hexdec($matches[3]));
        }
        elseif ($matches[1])
        {
            return self::chr_utf8($matches[3]);
        }
        elseif ($matches[3])
        {
        	// return "((&" . $matches[3] . ";))";
        	// return mb_convert_encoding('&'.$matches[3].';', 'UTF-8', 'HTML-ENTITIES');
        	return html_entity_decode('&'.$matches[3].';');
        }

        return false;
    }
852430
protected function replace(array $match): string
    {
        $character = $this->getOption('character');
        $mention = Str::title(str_replace($character, '', trim($match[0])));

        $route = config('mentions.pools.' . $this->getOption('pool') . '.route');

        $link = $route . $mention;

        return " [{$character}{$mention}]($link)";
    }
682726
public function heredocRealOverride($matches)
    {
        $this->record($matches[0], null);
        $this->posShift(strlen($matches[0]));
        // don't need this anymore
        $this->removePattern('HEREDOC_NL');
        assert($this->heredoc !== null);
        $delim = preg_quote($this->heredoc);
        $substr = $this->scanUntil('/^' . $delim . '\\b/m');
        if ($substr !== null) {
            $this->record($substr, 'HEREDOC');
            $delim_ = $this->scan('/' . $delim . '/');
            assert($delim !== null);
            $this->record($delim_, 'DELIMITER');
        } else {
            $this->record($this->rest(), 'HEREDOC');
            $this->terminate();
        }
    }