python - 为什么这个 Jinja nl2br 过滤器会转义 <br >'s but not <p>' s?

标签 python regex flask jinja2

我正在尝试实现 this金贾nl2br筛选。它工作正常,除了 <br>它添加的正在被转义。这对我来说很奇怪,因为 <p>的没有被转义,它们都在同一个字符串中。

我正在使用 flask ,所以 Jinja autoescape已启用。当我找到 this guy 时,我真的很有希望说autoescapeescape(value)可能导致双重转义,但删除了 escape()没有帮助。

这是我修改后的代码及其输出:

@app.template_filter()
@evalcontextfilter
def nl2br(eval_ctx, value):
    _paragraph_re = re.compile(r'(?:\r\n|\r(?!\n)|\n){2,}')
    result = u'\n\n'.join(u'<p>%s</p>' % escape(p.replace(u'\r\n', u'<br>\n')) for p in _paragraph_re.split(value))
    if eval_ctx.autoescape:
        result = Markup(result)
    return result

输入:

u'1\r\n2\r\n\r\n3\r\n4\r\n\r\n5\r\n6\r\n7'

输出:

<p>1&lt;br&gt;
2</p>

<p>3&lt;br&gt;
4</p>

<p>5&lt;br&gt;
6&lt;br&gt;
7</p>

期望的输出:

<p>1<br>2</p>

<p>3<br>4</p>

<p>5<br>6<br>7</p>

可能导致 <br> 的原因要转义但允许 <p>的?

最佳答案

nl2br过滤器不能正确处理标记对象。如果value是 Markup,然后插入 <br>标签将被转义。要修复它,<br>标记也必须是标记:

@app.template_filter()
@evalcontextfilter
def nl2br(eval_ctx, value):
    _paragraph_re = re.compile(r'(?:\r\n|\r(?!\n)|\n){2,}')
    result = u'\n\n'.join(u'<p>%s</p>' % p.replace(u'\n', Markup('<br>\n'))
                                         for p in _paragraph_re.split(value))
    if eval_ctx.autoescape:
        result = Markup(result)
    return result

注意:我将行结尾标准化为 \n .

这是对正在发生的事情的更详细解释:

拆分 Markup对象,产生许多Markup对象:

>>> Markup("hello there").split()
[Markup(u'hello'), Markup(u'there')]

根据 Jinja's documentation for Markup :

Operations on a markup string are markup aware which means that all arguments are passed through the escape() function.

回顾nl2br的主要改造,我们可以看到发生了什么以及为什么它不起作用:

result = u'\n\n'.join(u'<p>%s</p>' % p.replace(u'\n', u'<br>\n')
                                     for p in _paragraph_re.split(value))

u'\n\n'u'<br>\n'是 unicode 字符串,但是 pMarkup已从 value 拆分出来,这是一个标记对象。 p.replace尝试将 unicode 字符串添加到标记对象 p ,但 Markup 对象首先正确拦截并转义字符串。

<p>由于 Python 如何组装最终字符串,标签不会被转义,因为 %格式化方法在 unicode 字符串上调用,它使用传递给它的元素的 unicode 表示。标记元素已经被声明为安全的,因此它们不会被进一步转义。 result以 unicode 字符串结束。

关于python - 为什么这个 Jinja nl2br 过滤器会转义 <br >'s but not <p>' s?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12523725/

相关文章:

python - OpenCL 产生错误的计算

javascript - 如何检查文本是否突出显示(跨浏览器)

python打印正则表达式匹配产生空列表

python - 与继承类的多对一关系

python - Jinja2中模板的动态使用

python - 迭代并追加列表

python - 如何使用 Python 在 Airflow DAG 中导入外部脚本?

Python 预定义的 __str__ 方法行为异常

Javascript、正则表达式 - 从头开始​​获取数字

php - 重定向到 Flask 中的 PHP 文件