问题
I'm using Jinja with Flask (autoescape enabled) and I'm attempting to apply this filter
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
The problem with it is that it never applies <br>
s and always applies <p>
s around each line.
If I type:
1
2
3
4
in a textarea
, it gets saved to the DB as "u'1\r\n2\r\n\r\n3\r\n4'" and when put in Jinja with the |nl2br
filter it comes out as
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
I'm looking for it to be
<p>1<br>2</p>
<p>3<br>4</p>
this regular expression method seems like overkill for what I'm after.
Please tell me there is a simpler way to accomplish this as I've been pulling my hair out all day trying to figure it out...
回答1:
Simpler no, but how about only slightly more complicated? Try it with this regex:
(?:\r\n|\r(?!\n)|\n){2,}
The original regex matches \r\n
as a single line separator at first, but it's required to match two of them, so it backtracks and matches it as \r
followed by \n
. The negative lookahead, (?!\n)
, prevents it from matching \r
alone if the next character is \n
.
来源:https://stackoverflow.com/questions/12521127/is-there-a-better-way-to-apply-a-nl2br-filter-with-jinja-flask