Returns a regular expression that will match a given tag in an
SGML string.

@param string $tag_name
@param array $close_tags
@return string
512639
function tagMatcher($tag_name, $close_tags = null)
    {
        $expr = $this->_tag_expr;

        if ($close_tags) {
            $options = implode("|", array_merge(array($tag_name), $close_tags));
            $closer = sprintf("(?:%s)", $options);
        } else {
            $closer = $tag_name;
        }

        $expr = sprintf($expr, $tag_name, $closer);
        return sprintf("/%s/%s", $expr, $this->_re_flags);
    }
182410
def _handle_single_tag_end(self):
        """"""
        stack = self._stack
        # We need to find the index of the TagCloseOpen token corresponding to
        # the TagOpenOpen token located at index 0:
        depth = 1
        for index, token in enumerate(stack[2:], 2):
            if isinstance(token, tokens.TagOpenOpen):
                depth += 1
            elif isinstance(token, tokens.TagCloseOpen):
                depth -= 1
                if depth == 0:
                    break
            elif isinstance(token, tokens.TagCloseSelfclose):
                depth -= 1
                if depth == 0:  # pragma: no cover (untestable/exceptional)
                    raise ParserError(
                        "_handle_single_tag_end() got an unexpected "
                        "TagCloseSelfclose")
        else:  # pragma: no cover (untestable/exceptional case)
            raise ParserError("_handle_single_tag_end() missed a TagCloseOpen")
        padding = stack[index].padding
        stack[index] = tokens.TagCloseSelfclose(padding=padding, implicit=True)
        return self._pop()
77715
function _tag_close( &$parser, $tag ) {
		$this->currentElement = '';

		switch( strtoupper( $tag ) ) {
			case 'TABLE':
				$this->parent->addSQL( $this->create( $this->parent ) );
				xml_set_object( $parser, $this->parent );
				$this->destroy();
				break;
			case 'FIELD':
				unset($this->current_field);
				break;

		}
	}
463206
def _handle_tag_close_close(self):
        """"""
        strip = lambda tok: tok.text.rstrip().lower()
        closing = self._pop()
        if len(closing) != 1 or (not isinstance(closing[0], tokens.Text) or
                                 strip(closing[0]) != strip(self._stack[1])):
            self._fail_route()
        self._emit_all(closing)
        self._emit(tokens.TagCloseClose())
        return self._pop()
167215
public function tag($name) {
		if (!isset($this->_tags[$name])) {
			return false;
		}
		foreach ($this->_tags[$name] as $item) {
			return $item;
		}
	}
317944
def matches_tags?(tag_expr)
      Cucumber::Core::Gherkin::TagExpression.new(tag_expr).evaluate(
        tags.map { |tag| Cucumber::Core::Ast::Tag.new(nil, tag) }
      )
    end
350381
public static function buildHtmlElement($name, array $attributes = [], $content = null, $closeEmptyTag = true, array $cssClasses = []): string
    {
        $html = '<' . $name . self::buildAttrs($attributes, $cssClasses);
        if ($content !== null) {
            $html .= '>' . $content . '</' . $name . '>';
        } else {
            $html .= $closeEmptyTag ? ' />' : '>';
        }
        return $html;
    }
1353867
public static String getOpeningTag(String tag, Map<String, String> attributes)
	{
		StringBuffer _result = new StringBuffer();
		Map<String, String> _attributes = (null != attributes) ? attributes : EMPTY_MAP;
		return doAppendOpeningTag(_result, tag, _attributes).toString();
	}
200540
function readCloseTag() {
		let start = getSourcePoint(),
			match = tagCloseRegex.exec(source.substr(pos))
		if (!match) {
			throwSyntaxError('Invalid close tag')
		}
		advanceTo(pos + match[0].length)
		let end = getSourcePoint()
		return {
			type: 'tag-close',
			start,
			end,
			name: match[1].toLowerCase()
		}
	}
603642
def handle_endtag(self, tagName):
        '''
            
        '''
        inTag = self._inTag
        try:
            # Handle closing tags which should have been closed but weren't
            foundIt = False
            for i in range(len(inTag)):
                if inTag[i].tagName == tagName:
                    foundIt = True
                    break

            if not foundIt:
                sys.stderr.write('WARNING: found close tag with no matching start.\n')
                return

            while inTag[-1].tagName != tagName:
                oldTag = inTag.pop()
                if oldTag.tagName in PREFORMATTED_TAGS:
                    self.inPreformatted -= 1

                self.currentIndentLevel -= 1

            inTag.pop()
            if tagName != INVISIBLE_ROOT_TAG:
                self.currentIndentLevel -= 1
            if tagName in PREFORMATTED_TAGS:
                self.inPreformatted -= 1
        except:
            pass
948802
function getOpenTagParams(tag, tmplRule) {
  var pattern = tmplRule.openTagParams,
      matchArr,
      ret;

  while (matchArr = pattern.exec(tag)) {
    var key = matchArr[1];

    if (key === '/') {
      //If match to the last of "/", then continue the loop.
      continue;
    }

    if (!ret) {
      ret = [];
    }

    var value = matchArr[8],
        onlyBrace = matchArr[4] != null ? matchArr[4] : matchArr[6],
        onlyKey = false;

    if (value != null) {
      value = clearQuot(value); //Remove quotation marks
    } else {
      value = key; //Match to Similar to "checked" or "disabled" attribute.

      if (!onlyBrace) {
        onlyKey = true;
      }
    } //Removed at the end of "/>", ">" or "/".


    if (!matchArr[9] && !matchArr[10]) {
      if (/\/>$/.test(value)) {
        value = value.substr(0, value.length - 2);
      } else if (/>$/.test(value) || /\/$/.test(value)) {
        value = value.substr(0, value.length - 1);
      }
    } //Transform special key


    var hasColon = void 0;

    if (key[0] === ':') {
      key = key.substr(1);
      hasColon = true;
    }

    ret.push({
      key: key,
      value: value,
      onlyBrace: onlyBrace,
      hasColon: hasColon,
      onlyKey: onlyKey
    });
  }

  return ret;
}
1281028
private static function sanitizeTag($tag, $allowed = null, $resetStack = false)
    {
        static $stack = [];
        if ($resetStack) {
            $ret = $stack;
            $stack = [];
            return $ret;
        }

        $tag = substr($tag, 1, -1); // strip off leading '<' and trailing '>'
        if ($tag[0] == '/') {
            preg_match('/^\w+/', substr($tag, 1), $m);
            $closingTag = strtolower($m[0]);
            $localStack = [];

            if (null !== $allowed
                && (is_array($allowed) && !array_key_exists($closingTag, $allowed))
                || (is_callable($allowed) && !call_user_func($allowed, $closingTag))
            ) {
                return '<!-- ' . htmlspecialchars($tag) . ' -->';
            }

            do {
                if (!count($stack)) {
                    $stack = array_reverse($localStack);
                    // tag was never opened. Drop closing tag
                    return '';
                }
                $top = array_pop($stack);
                $localStack[] = $top;
            } while (strtolower($top) != $closingTag);
            $ret = '';
            foreach ($localStack as $needClose) {
                $ret .= '</' . $needClose . '>';
            }

            return $ret;
        } else {
            $ret = '';
            $attributes = [];
            preg_match('/^[\w-:]+/', $tag, $m);
            $tagName = strtolower($m[0]);
            if (null !== $allowed
                && (is_array($allowed) && !array_key_exists($tagName, $allowed))
                || (is_callable($allowed) && !call_user_func($allowed, $tagName))
            ) {
                return '<!-- ' . htmlspecialchars($tag) . ' -->';
            }

            $paragraphLevelElements = ['p', 'h6', 'h5', 'h4', 'h3', 'h2', 'h1', 'table', 'ul', 'div'];
            $inlineElements = ['span', 'b', 'i', 'u', 'span', 'strong', 'em', 'a', 'sup', 'sub'];
            $selfClosingElements = ['li', 'td', 'th', 'tr'];
            $forcedParents = ['li' => ['ul', 'ol']];

            if (count($stack) && in_array($tagName, $paragraphLevelElements)) {
                while (in_array(end($stack), array_merge($paragraphLevelElements, $inlineElements))) {
                    $ret .= '</' . array_pop($stack) . '>';
                }
            }
            if (count($stack) && in_array($tagName, $selfClosingElements)) {
                while (in_array(end($stack), $inlineElements)) {
                    $ret .= '</' . array_pop($stack) . '>';
                }
                if (end($stack) === $tagName) {
                    $ret .= '</' . array_pop($stack) . '>';
                }
            }

            if (array_key_exists($tagName, $forcedParents) && !in_array(end($stack), $forcedParents[$tagName])) {
                // if the parent would close paragraph or inline elements, do it now.
                if (count($stack) && in_array($forcedParents[$tagName][0], $paragraphLevelElements)) {
                    while (in_array(end($stack), array_merge($paragraphLevelElements, $inlineElements))) {
                        $ret .= '</' . array_pop($stack) . '>';
                    }
                }
                $ret .= '<' . $forcedParents[$tagName][0] . '>';
                $stack[] = $forcedParents[$tagName][0];
            }

            if (substr($tag, -1) == '/') {
                $isEmpty = true;
            } else {
                $isEmpty = in_array($tagName, ['br', 'img', 'input', 'param', 'isindex', 'area']);
            }
            for ($i = strlen($m[0]); $i < strlen($tag); true) {
                $preI = $i;

                $chunk = substr($tag, $i);

                if (preg_match('/^([\w-]+)\s*=\s*\"([^"]*)\"?/', $chunk, $m)) {
                    $attributes[$m[1]] = $m[2];
                    $i += strlen($m[0]);
                } elseif (preg_match('/^([\w-]+)\s*=\s*\'([^\']*)\'?/', $chunk, $m)) {
                    $attributes[$m[1]] = $m[2];
                    $i += strlen($m[0]);
                } elseif (preg_match('/^([\w-]+)=(\S+)/', $chunk, $m)) {
                    $attributes[$m[1]] = $m[2];
                    $i += strlen($m[0]);
                } elseif (preg_match('/^(\w+)/', $chunk, $m)) {
                    $attributes[$m[1]] = $m[1];
                    $i += strlen($m[0]);
                } else {
                    // drop character
                    $i++;
                }
                assert($i != $preI);
            }

            $ret .= '<';
            $ret .= $tagName;
            if (count($attributes)) {
                foreach ($attributes as $attrName => $value) {
                    $callback = null;
                    if (is_callable($allowed)) {
                        $callback = $allowed;
                    } elseif (is_array($allowed) && isset($allowed[$tagName]) && is_callable($allowed[$tagName])) {
                        $callback = $allowed[$tagName];
                    } elseif (is_array($allowed[$tagName]) && isset($allowed[$tagName][$attrName])) {
                        $callback = $allowed[$tagName][$attrName];
                    }
                    if (null !== $callback) {
                        $value = call_user_func($callback, $tagName, $attrName, $value);
                    }
                    if (false === $value) {
                        continue;
                    }
                    if (!preg_match('/^[a-z_-]/', $attrName)) {
                        // drop malformed attribute name
                        continue;
                    }
                    $ret .= ' ';
                    $ret .= sprintf('%s="%s"', $attrName, str_replace('"', '&quot;', $value));
                }
            }
            if ($isEmpty) {
                $ret .= ' /';
            } else {
                $stack[] = $tagName;
            }
            $ret .= '>';
            return $ret;
        }
    }
549144
public function getTag(string $name, $default = null)
    {
        return isset($this->tags[$name]) ? $this->tags[$name] : $default;
    }
984274
def _match_tag_regex(self, event_tag, search_tag):
        '''
        
        '''
        return self.cache_regex.get(search_tag).search(event_tag) is not None
1309639
private static Tag readTagFromBuffer(BufferedReader br, boolean close) {
    int id = 0;
    String name = "", forceDescription = null;
    ArrayList<String> types = new ArrayList<>();
    String cardinality = "";
    String defaultValue = "";
    String typedef = null;
    String description = null;
    String[] valueCodes = null;
    String[] valueDescriptions = null;

    try {
      String sCurrentLine;
      boolean readingTypes = false;
      while ((sCurrentLine = br.readLine()) != null) {
        if (sCurrentLine.contains("\"id\"")) {
          String sid = sCurrentLine.substring(sCurrentLine.indexOf(":") + 1).replace(",", "").trim();
          id = Integer.parseInt(sid);
        } else if (sCurrentLine.contains("\"name\"")) {
          String sval = sCurrentLine.substring(sCurrentLine.indexOf(":") + 1).replace("\"", "").replace(",", "").trim();
          name = sval;
        } else if (sCurrentLine.contains("\"forceDescription\"")) {
          String sval = sCurrentLine.substring(sCurrentLine.indexOf(":") + 1).replace("\"", "").replace(",", "").trim();
          forceDescription = sval;
        } else if (sCurrentLine.contains("\"cardinality\"")) {
          String sval = sCurrentLine.substring(sCurrentLine.indexOf(":") + 1).replace("\"", "").replace(",", "").trim();
          cardinality = sval;
        } else if (sCurrentLine.contains("\"defaultValue\"")) {
          String sval = sCurrentLine.substring(sCurrentLine.indexOf(":") + 1).replace("\"", "").replace(",", "").trim();
          defaultValue = sval;
        } else if (sCurrentLine.contains("\"valueCodes\"")) {
          sCurrentLine = br.readLine();
          valueCodes = sCurrentLine.split(",");
        } else if (sCurrentLine.contains("\"description\"")) {
          description = sCurrentLine.substring(sCurrentLine.indexOf(":") + 1).replace("\"", "").replace(",", "").trim();
        } else if (sCurrentLine.contains("\"valueDescriptions\"")) {
          sCurrentLine = br.readLine();
          valueDescriptions = sCurrentLine.split(",");
        } else if (sCurrentLine.contains("\"typedef\"")) {
          String sval = sCurrentLine.substring(sCurrentLine.indexOf(":") + 1).replace("\"", "").replace(",", "").trim();
          typedef = sval;
        } else if (sCurrentLine.contains("\"type\"")) {
          readingTypes = true;
        } else if (sCurrentLine.contains("],")) {
          readingTypes = false;
        } else if (readingTypes) {
          String sval = sCurrentLine.replace("\"", "").replace(",", "").trim();
          types.add(sval);
        }
      }
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        //br.reset();
        if (br != null && close) br.close();
      } catch (IOException ex) {
        ex.printStackTrace();
      }
    }

    Tag tag = new Tag(id, name, types, cardinality, defaultValue, typedef, forceDescription);
    tag.setDescription(description);
    tag.createValuesDictionary();
    if (valueCodes != null && valueDescriptions != null && valueCodes.length == valueDescriptions.length) {
      HashMap<String, String> values = new HashMap<String, String>();
      for (int i=0;i<valueCodes.length;i++) {
        values.put(valueCodes[i].trim(), valueDescriptions[i].trim().replace("\"", ""));
      }
      tag.setValues(values);
    }

    tagMap.put(tag.getId(), tag);
    tagNames.put(tag.getName(), tag);
    return tag;
  }
482234
public function uniqueSlug($slug_str, $tag_name)
	{
		$model = $this->tagModelString();
		if (!empty($slug_str) && $tag = $model::where('slug', $slug_str)->first()) {
			// 只有当 slug 一样但 tagname 不一样的情况下，才自动设置随机 slug 后缀
			if ($tag->name != $this->normalizeTagName($tag_name)) {
				$slug_str .= '-'. mt_rand(1000, 9999);
			}
		}
		return $slug_str;
	}
400405
function matchClosing(input, tagname, html) {
  var closeTag = '</' + tagname + '>',
      openTag  = new RegExp('< *' + tagname + '( *|>)', 'g'),
      closeCount = 0,
      openCount = -1,
      from, to, chunk
      ;

  from = html.search(input);
  to = from;

  while(to > -1 && closeCount !== openCount) {
    to = html.indexOf(closeTag, to);
    if (to > -1) {
      to += tagname.length + 3;
      closeCount ++;
      chunk = html.slice(from, to);
      openCount = chunk.match(openTag).length;
    }
  }
  if (to === -1) {
    throw new Error('Unmatched tag ' + tagname + ' in ' + html)
  }

  return chunk;
}