Есть ли лучший способ применить фильтр nl2br с Jinja/Flask?

Я использую 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

Проблема в том, что он никогда не применяет <br>s и всегда применяет <p>s вокруг каждой строки.

Если я наберу:

1
2

3
4

в textarea он сохраняется в БД как "u'1\r\n2\r\n\r\n3\r\n4'", а когда он помещается в Jinja с фильтром |nl2br, он выглядит как

<p>1</p>

<p>2</p>

<p>3</p>

<p>4</p>

Я ищу, чтобы это было

<p>1<br>2</p>
<p>3<br>4</p>

этот метод регулярного выражения кажется излишним для того, что мне нужно.

Пожалуйста, скажите мне, что есть более простой способ сделать это, так как я весь день рвал на себе волосы, пытаясь понять это...


person chrickso    schedule 20.09.2012    source источник
comment
Любой, кто попытается использовать этот пример, будет хорошо обслужен, если прочитает и поймет ответ на stackoverflow.com/a/21154829/1709587, который исправляет другую, не связанную с этим ошибку в этом фрагменте nl2br. Или, если уж на то пошло, используйте пример nl2br фильтра официальной документации из jinja.pocoo. org/docs/api/#custom-filters вместо этого плохо работающего неофициального фрагмента.   -  person Mark Amery    schedule 17.04.2019


Ответы (1)


Проще нет, а как насчет того, чтобы чуть посложнее? Попробуйте это с этим регулярным выражением:

(?:\r\n|\r(?!\n)|\n){2,}

Исходное регулярное выражение сначала сопоставляет \r\n как разделитель одной строки, но требуется, чтобы оно соответствовало двум из них, поэтому оно откатывается и сопоставляет его как \r, за которым следует \n. Отрицательный просмотр вперед, (?!\n), предотвращает совпадение только с \r, если следующим символом является \n.

person Alan Moore    schedule 20.09.2012
comment
Это хорошее объяснение и хорошее исправление, но вы упустили шанс сделать немного больше добра в мире, вернув свое исправление в официальную документацию, которая (на момент написания этого комментария) все еще использует неработающее регулярное выражение из вопрос по адресу jinja.pocoo.org/docs/2.10/api/#custom- фильтры. Я скопировал ваше исправление и предложил его в патче для официальной документации (с указанием вашего имени) на github. .com/pallets/jinja/pull/929; Надеюсь, вы одобрите! - person Mark Amery; 25.11.2018
comment
Я должен был подумать об этом. Спасибо, Марк. - person Alan Moore; 09.12.2018