问题
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