Get two arrays suitable for str_replace to replace all variables.

@param array $matches
@param array $data

@return array
973899
protected function getSearchAndReplace(array $matches, array $data)
    {
        $count = count($matches);
        $alreadySetted = [];
        $search = [];
        $replace = [];

        for ($i = 0, $m = 0; $i < $count; ++$i) {
            if (isset($alreadySetted[$matches[$i]])) {
                continue;
            }

            $value = $this->extractValue($matches[$i], $data);

            if ($value === null) {
                continue;
            }

            $search[$m] = $matches[$i];
            $replace[$m] = $value;
            $alreadySetted[$matches[$i]] = true;
            ++$m;
        }

        return [$search, $replace];
    }
386246
private function _filter(array $matches)
    {
        $filters = explode('|', $matches[0]);
        $var = $filters[0];
        unset($filters[0]);
        foreach ($filters as $filter) {
            $params = explode(':', $filter);
            $filterName = $params[0];
            unset($params[0]);
            $array = 'array(';
            foreach ($params as $param) {
                $array .= $param . ',';
            }
            $array = trim($array, ',') . ')';
            $var = 'getFilter(\'' . $filterName . '\')->setOptions(' . $array . ')->filter(' . $var . ')';
        }
        return $var;
    }
412731
protected function processImportRow($rowData, $matches)
    {
        $newRow = [];

        foreach ($matches as $columnIndex => $dbNames) {
            $value = array_get($rowData, $columnIndex);
            foreach ((array) $dbNames as $dbName) {
                $newRow[$dbName] = $value;
            }
        }

        return $newRow;
    }
1302031
protected function removeNumericAndEmpty(array &$matches)
    {
        foreach ($matches as $idx => $val) {
            if (is_int($idx) || '' === $val) {
                unset($matches[$idx]);
            }
        }
    }
140614
protected function matchOr($data, array $matchers)
    {
        foreach ($matchers as $matcher) {
            if ($matcher($data)) {
                return true;
            }
        }
        return false;
    }
1250679
public function _parseParams(array $matches)
    {
        $params = array();
        foreach ($matches as $k => $v) {
            if (is_numeric($k)) {
                if ($k === 0) {
                    continue;
                }
                $params[] = $v;
            } else {
                $params[$k] = $v;
            }
        }
        return new Set($params);
    }
1005516
private function mapMatches(array $matches): array
    {
        $numbers = [];

        if (array_key_exists('major', $matches) && mb_strlen($matches['major'])) {
            $numbers['major'] = $matches['major'];
        }
        if (array_key_exists('minor', $matches) && mb_strlen($matches['minor'])) {
            $numbers['minor'] = $matches['minor'];
        }
        if (array_key_exists('micro', $matches) && mb_strlen($matches['micro'])) {
            $numbers['micro'] = $matches['micro'];
        }
        if (array_key_exists('patch', $matches) && mb_strlen($matches['patch'])) {
            $numbers['patch'] = $matches['patch'];
        }
        if (array_key_exists('micropatch', $matches) && mb_strlen($matches['micropatch'])) {
            $numbers['micropatch'] = $matches['micropatch'];
        }
        if (array_key_exists('stability', $matches) && mb_strlen($matches['stability'])) {
            $numbers['stability'] = $matches['stability'];
        }
        if (array_key_exists('build', $matches) && mb_strlen($matches['build'])) {
            $numbers['build'] = $matches['build'];
        }

        return $numbers;
    }
211715
private function replaceNumberedHolder(array $matches)
    {
        $holder = ':numbered_holder_' . $this->count_numbered;
        $this->count_numbered ++;
        return (isset($matches[1]) ? $matches[1] : '') . $holder . (isset($matches[2]) ? $matches[2] : '');
    }
661591
private function getNamedPatterns($matches)
    {
        foreach ($matches as $key => $value) {
            if (!is_string($key) || strlen($value) < 1) {
                unset($matches[$key]);
            }
        }

        return $matches;
    }
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;
    }
1183160
protected function normalizeShortOptions(array $matches) {
        $newMatches = [];

        foreach ($matches as $match) {
            if ( ! str_starts_with($match, '--')
                && str_starts_with($match, '-')
                && strlen($match) > 2
            ) {
                // convert options like -abc to -a -b -c
                foreach (str_split(substr($match, 1)) as $match) {
                    $newMatches[] = "-$match";
                }
            } else {
                $newMatches[] = $match;
            }
        }

        return $newMatches;
    }
981736
public static function getVariables($matches, &$vars = null)
    {
        if (!$matches) {
            return [];
        }

        if ($vars === null) {
            $vars = [];
        }

        foreach ($matches as $i => $var) {
            if (is_numeric($i)) {
                continue;
            }

            if (strpos((string) $var, '/') !== false) {
                $var = explode('/', (string) $var);
            }

            $vars[$i] = $var;
        }

        return $vars;
    }
497073
public function replace(string $text, Array $data): string {
    $replaceText = $text;
    if (!empty($text) && count($data)) {
      foreach ($data as $key => $value) {
        $replaceText = preg_replace("#(\{data\:{$key}\})#i", $value, $replaceText);
      }
    }
    return $replaceText;
  }
785366
protected static function replaceBlock(array $matches)
    {
        $matches[3] = self::removeTrailingNewline($matches[3]);

        if (preg_match_all(self::$regex, self::$childSource, $override) && in_array($matches[2], $override[2])) {
            $key      = array_search($matches[2], $override[2]);
            $override = self::removeTrailingNewline($override[3][$key]);

            $l = stripslashes(self::$l);
            $r = stripslashes(self::$r);

            if (self::$lastReplacement) {
                return preg_replace('/' . self::$l . '\$dwoo\.parent' . self::$r . '/is', $matches[3], $override);
            }

            return $l . 'block ' . $matches[1] . $matches[2] . $matches[1] . $r . preg_replace('/' . self::$l . '\$dwoo\.parent' . self::$r . '/is', $matches[3], $override) . $l . '/block' . $r;
        }

        if (preg_match(self::$regex, $matches[3])) {
            return preg_replace_callback(self::$regex, array(
                'Dwoo\Plugins\Functions\PluginExtends',
                'replaceBlock'
            ), $matches[3]);
        }

        if (self::$lastReplacement) {
            return $matches[3];
        }

        return $matches[0];
    }
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;
    }
786215
public function strip_php_tags($data)
    {
        if (is_array($data)) {
            foreach ($data as $key=>$value) {
                $data[$key] = $this->strip_php_tags($value);
            }
            return $data;
        }
        return addslashes(htmlspecialchars(strip_tags($data)));
    }
1078845
protected function getVariables($matches)
    {
        $variables = array();
        
        if (!is_array($matches)) {
            return $variables;
        }
        
        array_shift($matches);
        
        foreach ($matches as $path) {
            $variables = array_merge($variables, explode('/', $path));
        }
        
        foreach ($variables as $i => $variable) {
            if (!$variable) {
                unset($variables[$i]);
            }
        }
        
        return array_values($variables);
    }