解决Can't parse entities can't find end of the entity starting at byte offset 6643

49 min read

The error message says that you caption text is no valid markdown. Could be that you need to escape something (use helpers.util.escape_markdown) for that.

错误消息显示您的字幕文本没有有效的markdown。可能是你需要逃避一些事情(使用 helpers.util.escape_markdown )。
On a side note, you should use MarkdownV2, as Markdown is legacy mode now.
另外,您应该使用MarkdownV2,因为Markdown现在是传统模式。

escape_markdown 具体代码如下

def escape_markdown(text: str, version: int = 1, entity_type: str = None) -> str:
    """Helper function to escape telegram markup symbols.
    Args:
        text (:obj:`str`): The text.
        version (:obj:`int` | :obj:`str`): Use to specify the version of telegrams Markdown.
            Either ``1`` or ``2``. Defaults to ``1``.
        entity_type (:obj:`str`, optional): For the entity types
            :tg-const:`telegram.MessageEntity.PRE`, :tg-const:`telegram.MessageEntity.CODE` and
            the link part of :tg-const:`telegram.MessageEntity.TEXT_LINK`, only certain characters
            need to be escaped in :tg-const:`telegram.constants.ParseMode.MARKDOWN_V2`.
            See the official API documentation for details. Only valid in combination with
            ``version=2``, will be ignored else.
    """
    if int(version) == 1:
        escape_chars = r"_*`["
    elif int(version) == 2:
        if entity_type in ["pre", "code"]:
            escape_chars = r"\`"
        elif entity_type == "text_link":
            escape_chars = r"\)"
        else:
            escape_chars = r"\_*[]()~`>#+-=|{}.!"
    else:
        raise ValueError("Markdown version must be either 1 or 2!")

    return re.sub(f"([{re.escape(escape_chars)}])", r"\\\1", text)

使用Go 进行改写

import "regexp"

func escapeMarkdown(text string, version int, entityType string) string {
    var escapeChars string

    if version == 1 {
        escapeChars = `_ * [`
    } else if version == 2 {
        if entityType == "pre" || entityType == "code" {
            escapeChars = "`"
        } else if entityType == "text_link" {
            escapeChars = ")"
        } else {
            escapeChars = `_ * [] () ~ ` + ">#+-=|{}.!"
        }
    } else {
        panic("Markdown version must be either 1 or 2!")
    }

    re := regexp.MustCompile("([" + regexp.QuoteMeta(escapeChars) + "])")
    return re.ReplaceAllString(text, `\$1`)
}

regexp.MustCompile()函数将该正则表达式模式编译成一个正则表达式对象,可用于匹配字符串。模式是由多个部分组成的字符串拼接:

  • "(["是一个字符类的开括号,它将匹配其中任何一个字符。
  • regexp.QuoteMeta(escapeChars)用于转义escapeChars字符串中的任何特殊字符,使它们在正则表达式模式中被视为字面量字符。例如,如果escapeChars"_ * [",那么QuoteMeta()函数将返回"_ \* \["
  • "])"是该字符类的闭括号。

因此,例如,如果escapeChars"_ * [",那么这行代码创建的正则表达式模式将是"([_ \* \[])",用于匹配下划线、星号或左方括号中的任何一个字符。

regexp.QuoteMeta() 函数将其参数字符串中的任何特殊字符转义,以便它们在正则表达式模式中被视为字面量字符。

例如,如果传递给 regexp.QuoteMeta() 的参数是 "_ * [",则返回的字符串将是 "\_ \* \[",其中 \ 是一个转义字符,用于将特殊字符 _*[ 转义成字面量字符。

在这个特定的代码行中,escapeChars 是一个包含各种 Markdown 特殊字符的字符串,例如 _*[, ]()~>#+-=|.!。因此,将 escapeChars 传递给 regexp.QuoteMeta() 函数将对其中的特殊字符进行转义,以便它们可以在正则表达式模式中被视为字面量字符。

因此, 也可以改成如下的通用形式:

func EscapeMarkdown(text string) string {
	escapeChars := `\\_` + `*` + `[]()` + `~` + "`" + `>#+-=|{}.!`
	pattern := regexp.MustCompile("([" + regexp.QuoteMeta(escapeChars) + "])")
	return pattern.ReplaceAllString(text, "\$1")
}