有没有更好的方法来应用与Jinja/Flask的nl2br过滤器?

chr*_*kso 0 python regex template-engine jinja2 flask

可能重复:
为什么这个Jinja nl2br过滤器逃避了?而不是<p>?

我正在使用Jinja和Flask(启用自动启用),我正在尝试应用此过滤器

import re

from jinja2 import evalcontextfilter, Markup, escape

_paragraph_re = re.compile(r'(?:\r\n|\r|\n){2,}')

app = Flask(__name__)

@app.template_filter()
@evalcontextfilter
def nl2br(eval_ctx, value):
    result = u'\n\n'.join(u'<p>%s</p>' % p.replace('\n', '<br>\n') \
        for p in _paragraph_re.split(escape(value)))
    if eval_ctx.autoescape:
        result = Markup(result)
    return result
Run Code Online (Sandbox Code Playgroud)

它的问题在于它从不应用<br>s并且总是<p>在每条线周围应用s.

如果我输入:

1
2

3
4
Run Code Online (Sandbox Code Playgroud)

在a中textarea,它被保存到数据库中作为"u'1\r \n2\r \n\r \n \n \n \n\r \n \n \n \n4'",当使用|nl2br过滤器放入Jinja时,它会以

<p>1</p>

<p>2</p>

<p>3</p>

<p>4</p>
Run Code Online (Sandbox Code Playgroud)

我正在寻找它

<p>1<br>2</p>
<p>3<br>4</p>
Run Code Online (Sandbox Code Playgroud)

这个正则表达式方法对我所追求的东西来说似乎有些过分.

请告诉我有一种更简单的方法可以实现这一目标,因为我一整天都在拔头发试图解决这个问题......

Ala*_*ore 7

更简单没有,但怎么样只是稍微复杂一点?试试这个正则表达式:

(?:\r\n|\r(?!\n)|\n){2,}
Run Code Online (Sandbox Code Playgroud)

原始正则表达式首先匹配\r\n为单行分隔符,但是需要匹配其中的两个,因此它会回溯并匹配它,\r如下所示\n.如果下一个字符是(?!\n),则负向前瞻,阻止它\r单独匹配\n.

  • 这是一个很好的解释和一个很好的修复,但是您错过了通过将您的修复贡献给官方文档来为世界做更多好事的机会,该文档(在撰写此评论时)仍然使用来自问题见http://jinja.pocoo.org/docs/2.10/api/#custom-filters。我已经修复了你的问题,并在官方文档的补丁中提出了它(归功于你):https://github.com/pallets/jinja/pull/929;希望您能批准! (2认同)
  • 我应该想到这一点。谢谢,马克。 (2认同)