在Python 3.6中使用re.sub和jinja2.Markup转义?

时间:2017-07-18 06:20:30

标签: python-3.x flask escaping jinja2

所以我的Flask应用程序中有以下功能。

def markup_abbreviations(txt, match_map, match_regex):
    html = Markup.escape(txt)
    sub_template = Markup('<abbr title="%s">%s</abbr>')

    def replace_callback(m):
        return sub_template % (match_map[m.group(0)], m.group(0))

    return match_regex.sub(replace_callback, html)

示例参数:

txt = 'blah blah blah etc., blah blah'

match_map = {
    'etc.': 'et cetera',
    'usu.': 'usually',
}

match_regex = re.compile(
    '|'.join(r'\b' + re.escape(k) for k in match_map)
)

这非常有效并且将"etc."转换为"<abbr title=\"et cetera\">etc.</abbr>",依此类推在我的本地Python 3.3计算机上。

然后我想我想部署到Heroku,它说它只支持最新的python,即Python 3.6.1。它与我在当地获得的不同,但是,呃,无论如何。它的工作原理......主要是。

除了我上面的功能,现在给我"&lt;abbr title=&quot;et cetera&quot;&gt;etc.&lt;/abbr&gt;"

我假设在Python 3.3和Python 3.6之间,re.sub实现必须以某种方式改变,现在它不再使用传递的字符串方法来创建输出。因此,Markup的自动转义方法未被使用。而是从头开始构建新的str。这就是为什么re.sub现在只返回str而不再是Markup的原因。

如何在Python 3.6中将re.subjinja2.Markup一起使用,让我的功能再次运行?

1 个答案:

答案 0 :(得分:1)

Markup课程只是&#34;标记&#34;字符串对于html是安全的。这意味着当字符串放入模板时,不必对其进行转义。

re.sub()返回新的str对象时,您需要做的是将新对象标记为安全(将其包装在标记中)。

def markup_abbreviations(txt, match_map, match_regex):
    html = Markup.escape(txt)
    sub_template = '<abbr title="%s">%s</abbr>'

    def replace_callback(m):
        return sub_template % (match_map[m.group(0)], m.group(0))

    return Markup(match_regex.sub(replace_callback, html))

我检查了所有&#34;新的&#34;从Python 3.3到3.6并没有改变re模块的行为(有一些东西,但它不应该与你的问题相关联)。也许别人知道发生了什么......