Internal callback to escape characters
@param array $match A match from `preg_replace_callback()`
@return string
16961
private static function _escapeStringCallback(array $match): string
    {
        if (isset($match[2])) {
            return self::ESCAPE_SPECIALS[$match[2]]
                ?? \sprintf('\\x%02X', \ord($match[2]));
        }
        return '\\' . $match[1];
    }
161234
protected function _censorCallback($matches) {
        $length = mb_strlen(trim($matches[0]));
        $censored = '';
        $symbols = str_shuffle('*@#$*!?%');
        $i = 0;
        $s = 0;

        if ($length > 10) {
            $length = 10;
        }

        while ($i < $length) {
            $censored .= $symbols[$s];

            $i++;
            $s++;

            if ($s > 7) {
                $s = 0;
            }
        }

        return $censored;
    }
390986
public function match(array $matches) {
        $params = explode(' ', $matches[1]);
        $paramsNum = count($params);
        $this->params[] = $params[0];

        if (1 == $paramsNum) {
            return sprintf($this->defaultRegx['char'], '+');
        }
        else if (2 == $paramsNum) {
            return sprintf($this->defaultRegx[$params[1]], '+');
        }
        else if (3 == $paramsNum) {
            return sprintf($this->defaultRegx[$params[1]], $params[2] > 0 ? '{' . $params[2] . '}' : '*');
        }
        else if (4 == $paramsNum) {
            return sprintf($this->defaultRegx[$params[1]], '{' . $params[2] . ',' . $params[3] . '}');
        }
    }
1275720
private function _decode_entity(array $match): string
    {
        // init
        $str = $match[0];

        // protect GET variables without XSS in URLs
        if (\preg_match_all("/[\?|&]?[\\p{L}0-9_\-\[\]]+\s*=\s*(?<wrapped>\"|\042|'|\047)(?<attr>[^\\1]*?)\\g{wrapped}/ui", $str, $matches)) {
            if (isset($matches['attr'])) {
                foreach ($matches['attr'] as $matchInner) {
                    $tmpAntiXss = clone $this;

                    $urlPartClean = $tmpAntiXss->xss_clean($matchInner);

                    if ($tmpAntiXss->isXssFound() === true) {
                        $this->_xss_found = true;

                        $str = \str_replace($matchInner, UTF8::rawurldecode($urlPartClean), $str);
                    }
                }
            }
        } else {
            $str = $this->_entity_decode(UTF8::rawurldecode($str));
        }

        return $str;
    }
1024422
protected function jsMatcher($matches)
    {
        $chr = $matches[0];
        if (strlen($chr) == 1) {
            return sprintf('\\x%02X', ord($chr));
        }
        $chr = $this->convertEncoding($chr, 'UTF-16BE', 'UTF-8');
        return sprintf('\\u%04s', strtoupper(bin2hex($chr)));
    }
266713
protected function javascriptEscaper(array $matches): string
	{
		$chr = $matches[0];

		if(strlen($chr) === 1)
		{
			return sprintf('\\x%02X', ord($chr));
		}

		$chr = mb_convert_encoding($chr, 'UTF-16BE', 'UTF-8');

		return sprintf('\\u%04s', strtoupper(bin2hex($chr)));
	}
904366
public function tags_preg_callback($matches)
    {
        switch (strtolower($matches[1])) {
        case 'b':
        case 'strong':
            return $this->_toupper($matches[3]);
        case 'th':
            return $this->_toupper("\t\t". $matches[3] ."\n");
        case 'h':
            return $this->_toupper("\n\n". $matches[3] ."\n\n");
        case 'a':
            // Remove spaces in URL (#1487805)
            $url = str_replace(' ', '', $matches[3]);
            return $this->_build_link_list($url, $matches[4]);
        }
    }
660437
public static function replace($match, $replace, $org)
    {
        //if $match satisfies regular expression
        if (is::regex($match)) {
            return preg_replace($match, $replace, $org);
        } else {
            return str_replace($match, $replace, $org);
        }
    }
139549
protected function cssEscaper(array $matches): string
	{
		$chr = $matches[0];

		if(strlen($chr) === 1)
		{
			$ord = ord($chr);
		}
		else
		{
			$chr = mb_convert_encoding($chr, 'UTF-16BE', 'UTF-8');

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

		return sprintf('\\%X ', $ord);
	}
604363
protected function getMatchArgs(array $match)
    {
        // Remove the first element, the matching regex
        array_shift($match);

        // Iterate through the arguments and remove any unwanted slashes
        foreach ($match as &$arg) {
            $arg = trim($arg, '/');
        }

        return $match;
    }
1123309
private function parse_match($match) {
    $match = trim($match);
    $docblock = new Docblock($match);
    $tags = $docblock->getTags();
    $element_values = array();

    if ($title = $docblock->getShortDescription()) {
      // Skip text strings that start with #
      // (e.g. source map comment)
      if (strpos($title, '#') === 0) {
        return $element_values;
      }
      
      $element_values['title'] = $title;
    }

    if ($description = $docblock->getLongDescription()) {
      $element_values['description'] = $description;
    }

    foreach ($tags as $tag) {
      $tag_name = $tag->getTagName();
      $tag_description = $this->clean_description($tag->getDescription());
      switch ($tag_name) {
        case 'code':
        case 'markup':
          // Default code language is markup
          $element_values['code_language'] = 'markup';
          // Hide rendered output by default
          $element_values['code_render'] = FALSE;
          // If tag name is markup render by default
          if ($tag_name == 'markup') {
            $element_values['code_render'] = TRUE;
          }
          // Look if a other code language is defined
          if (preg_match("#^\[(.*?)\]\n#s", $tag_description, $code_language_match)) {
            $element_values['code_language'] = $code_language_match[1];
            $tag_description = str_replace('[' . $code_language_match[1] . ']', '', $tag_description);
          }
          $element_values['code'] = trim($tag_description);
          break;

        case 'color':
          $colorsets = array();
          $colorset_elements = explode("\n", $tag_description);
          foreach ($colorset_elements as $colorset) {
            $color_elements = explode('|', $colorset);
            $colors = array();
            foreach ($color_elements as $color) {
              $color_arr = explode(':', $color);
              if (count($color_arr) > 1) {
                $colors[] = array(
                  'name' => trim($color_arr[0]),
                  'value' => trim($color_arr[1]),
                );
              }
              else {
                $colors[] = array('value' => $color_arr[0]);
              }
            }
            $colorsets[] = $colors;
          }
          $element_values['color'] = $colorsets;
          break;

        case 'variable':
          $variables = explode('|', $tag_description);
          $element_values['variable'] = '- ' . implode(";\n- ", $variables) . ';';
          break;

        default:
          $element_values[$tag_name] = $tag_description;
          break;
      }
    }
    return $element_values;
  }
1230234
protected static function h(array $matches)
    {
        $level = strlen($matches[1]);
        return sprintf('<h%d>%s</h%d>', $level, trim($matches[2]), $level);
    }
254364
public function extractValue(Array $match)
	{
		switch(gettype($match['value']))
		{
			case 'string':
				return $match['value'];
				break;
			case 'object':
				// Extract Closures
				if(get_class($match['value']) == 'Closure') {
					return $this->closureExtract($match);
				}
				// Extract Classes
				return $this->classExtract($match);
				break;
		}

		throw new Exceptions\UnexpectedMaskValue($match['value'], $match['raw']);
	}
33022
protected function _stripAbbreviations_callback($matches) {
		$abbr_word = $matches[1];
		$abbr_desc = $matches[2];
		if ($this->abbr_word_re) {
			$this->abbr_word_re .= '|';
		}
		$this->abbr_word_re .= preg_quote($abbr_word);
		$this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
		return ''; // String that will replace the block
	}
874585
protected function _preg_callback($matches)
    {
        switch (strtolower($matches[1])) {
            case 'b':
            case 'strong':
                return $this->_toupper($matches[3]);
            case 'th':
                return $this->_toupper("\t\t".$matches[3]."\n");
            case 'h':
                return $this->_toupper("\n\n".$matches[3]."\n\n");
            case 'a':
                // override the link method
                $link_override = null;
                if (preg_match('/_html2text_link_(\w+)/', $matches[4], $link_override_match)) {
                    $link_override = $link_override_match[1];
                }
                // Remove spaces in URL (#1487805)
                $url = str_replace(' ', '', $matches[3]);

                return $this->_build_link_list($url, $matches[5], $link_override);
        }

        return '';
    }
846956
protected function createRegex($matched)
	{
		$startSlash = $matched[1] ? true : false;
		$param      = $matched[2];
		$optional   = $matched[3] ? true : false;
		$pattern    = $matched[4] ?: null;

		$pattern = $this->conditions[$param] ?: $pattern ?: '[^/]+';

		$this->paramNames[] = $param;

		if ($startSlash)
		{
			$regex = ($optional ? "(/" : '/') .'(?P<' . $param . '>' . $pattern . ')'. ($optional ? ')?' : '');
		}
		else
		{
			$regex = '(?P<' . $param . '>' . $pattern . ')'. ($optional ? '?' : '');
		}

		return $regex;
	}
1215337
private function resolveTag(array $match)
    {
        $tagReflector = $this->createLinkOrSeeTagFromRegexMatch($match);
        if (!$tagReflector instanceof See && !$tagReflector instanceof Link) {
            return $match;
        }

        $link = $this->getLinkText($tagReflector);
        $description = (string) $tagReflector->getDescription();

        if ($this->isUrl($link)) {
            return $this->generateMarkdownLink($link, $description ?: $link);
        }

        $link = $this->resolveQsen($link);
        $element = $this->findElement($link);
        if (!$element) {
            return (string) $link;
        }

        return $this->resolveElement($element, $link, $description);
    }