private static string RemoveCustomTags(string textWithTags)
    {
        string textWithoutTags = textWithTags;

        foreach (var customTag in CustomTagTypes)
        {
            textWithoutTags = RichTextTag.RemoveTagsFromString(textWithoutTags, customTag);
        }

        return(textWithoutTags);
    }
    private static string RemoveUnityTags(string textWithTags)
    {
        string textWithoutTags = textWithTags;

        foreach (var unityTag in UnityTagTypes)
        {
            textWithoutTags = RichTextTag.RemoveTagsFromString(textWithoutTags, unityTag);
        }

        return(textWithoutTags);
    }
    /// <summary>
    /// 从字符串中移除富文本标签
    /// </summary>
    /// <param name="_textWithTags"></param>
    /// <param name="_tags"></param>
    /// <returns></returns>
    private static string RemoveTags(string _textWithTags, string[] _tags)
    {
        var textWithoutTags = _textWithTags;

        foreach (var tag in _tags)
        {
            textWithoutTags = RichTextTag.RemoveTagsFromString(textWithoutTags, tag);
        }

        return(textWithoutTags);
    }
    /// <summary>
    /// Gets the typed text at the specified visibleCharacterIndex. This is the text that should be written
    /// to the Text component.
    /// </summary>
    /// <returns>The <see cref="TypedText"/> generated at the specified visible character index.</returns>
    /// <param name="text">Text to parse.</param>
    /// <param name="visibleCharacterIndex">Visible character index (ignores tags).</param>
    public string GetTypedTextAt(string text, int visibleCharacterIndex)
    {
        var textAsSymbolList = CreateSymbolListFromText(text);

        // Split the text into shown and hide strings based on the actual visible characters
        int printedCharCount     = 0;
        var shownText            = string.Empty;
        var hiddenText           = string.Empty;
        var lastVisibleCharacter = char.MinValue;

        foreach (var symbol in textAsSymbolList)
        {
            if (printedCharCount <= visibleCharacterIndex)
            {
                shownText += symbol.Text;

                // Keep track of the visible characters that have been printed
                if (!symbol.IsTag)
                {
                    lastVisibleCharacter = symbol.Character.ToCharArray()[0];
                }
            }
            else
            {
                hiddenText += symbol.Text;
            }

            if (!symbol.IsTag)
            {
                printedCharCount++;
            }
        }

        var activeTags = GetActiveTagsInSymbolList(textAsSymbolList, visibleCharacterIndex);

        // Remove closing tags for active tags from hidden text (move to before color hide tag)
        foreach (var activeTag in activeTags)
        {
            hiddenText = RemoveFirstOccurance(hiddenText, activeTag.ClosingTagText);
        }

        // Remove all color tags from hidden text so that they don't cause it to be shown
        // ex: <color=clear>This should <color=red>be clear</color></color> will show 'be clear" in red
        hiddenText = RichTextTag.RemoveTagsFromString(hiddenText, "color");

        // Add the hidden text, provided there is text to hide
        if (!string.IsNullOrEmpty(hiddenText))
        {
            var hiddenTag = RichTextTag.ClearColorTag;
            hiddenText = hiddenText.Insert(0, hiddenTag.TagText);
            hiddenText = hiddenText.Insert(hiddenText.Length, hiddenTag.ClosingTagText);
        }

        // Add back in closing tags in reverse order
        for (int i = 0; i < activeTags.Count; ++i)
        {
            hiddenText = hiddenText.Insert(0, activeTags[i].ClosingTagText);
        }

        // Remove all custom tags since Unity will display them when printed (it doesn't recognize them as rich text tags)
        var printText = shownText + hiddenText;

        foreach (var customTag in CustomTagTypes)
        {
            printText = RichTextTag.RemoveTagsFromString(printText, customTag);
        }

        // Calculate Delay, if active
        var delay = 0.0f;

        foreach (var activeTag in activeTags)
        {
            if (activeTag.TagType == "delay")
            {
                try
                {
                    delay = activeTag.IsOpeningTag ? float.Parse(activeTag.Parameter) : 0.0f;
                }
                catch (System.FormatException e)
                {
                    var warning = string.Format(
                        "TypedTextGenerator found Invalid paramter format in tag [{0}]. " +
                        "Parameter [{1}] does not parse to a float. Exception: {2}",
                        activeTag,
                        activeTag.Parameter,
                        e);
                    Debug.Log(warning);
                    delay = 0.0f;
                }
            }
        }

        return(printText);
    }