Пользовательский шаблонный фильтр на основе регулярных выражений не находит первое целевое слово в строке (Django 2.1) - PullRequest
0 голосов
/ 06 февраля 2019

У меня есть пользовательский шаблонный фильтр на основе регулярных выражений, который находит и выделяет ключевое слово, введенное в поисковую систему, такую ​​как Google.Например, если пользователь ищет «торт», мой фильтр будет выделять «торт» в «Я только что съел торт».Вот код для фильтра:

@register.filter(needs_autoescape=True)
@stringfilter
def highlight(value, search_term, autoescape=True):
    # first compile the regex pattern using the search_term
    pattern = re.compile(re.escape(search_term), re.IGNORECASE)
    # now replace
    new_value = pattern.sub('<span class="highlight">\g<0></span>', value)
    return mark_safe(new_value)

Код для поисковой системы в views.py:

def query_search(request):
    articles = cross_currents.objects.all()
    search_term = ''
    if 'keyword' in request.GET:
        search_term = request.GET['keyword']
        articles = articles.annotate(similarity=Greatest(TrigramSimilarity('Title', search_term), TrigramSimilarity('Content', search_term))).filter(similarity__gte=0.03).order_by('-similarity')
    context = {'articles': articles, 'search_term': search_term}
    return render(request, 'query_search.html', context)

HTML-шаблон:

 <ul>
{% for article in articles %}
<li><a href="{% url 'search:article_detail' article.ArticleID %}">{{ article|highlight:search_term }}</a></li>
<p> {{ article.Content|highlight:search_term|show_excerpt:search_term }} </p>
{% endfor %}
</ul>

Проблема заключается вчто фильтр не выделяет первое встречающееся ключевое слово, а делает это со всеми остальными ключевыми словами.Например, если ключевое слово «торт» и предложение «мой торт - это торт из кондитерской», оно будет выделять только второй и третий «торт», но не первый.Любая идея, почему это так?

РЕДАКТИРОВАТЬ: вот код для фильтра show_excerpt (отображает текст, окружающий ключевое слово в результатах поиска, как в Google):

@register.filter(needs_autoescape=True)
@stringfilter
def show_excerpt(value, search_term, autoescape=True):
    #make data into string and lower#
    original_text = str(value)
    lower_original_text = original_text.lower()
    #make keyword into string and lower#
    keyword_string = str(search_term)
    lower_keyword_string = keyword_string.lower()
    #find the position of the keyword in the data#
    keyword_index = lower_original_text.find(lower_keyword_string)
    #Specify the beginning and ending positions of the excerpt#
    start_index = keyword_index 
    end_index = keyword_index + 3000
    #Define the position range of excerpt#
    excerpt = original_text[start_index:end_index]
    return mark_safe(excerpt)

1 Ответ

0 голосов
/ 06 февраля 2019

Я не вижу проблем с вашим highlight фильтром, но проблема может быть из-за фильтра show_excerpt.Из вашего предыдущего вопроса ясно видно, что вы хотите получить только 300 символов, существующих до и после ключевого слова поиска, и выделите только поисковый термин.

# modified show_excerpt to get the surrounded chars
@register.filter(needs_autoescape=True)
@stringfilter
def show_excerpt(value, search_term, autoescape=True):
    match = re.search('.{0,300}' + re.escape(search_term) + '.{0,300}', str(value), re.IGNORECASE)
    if match: return mark_safe(match.group())
    return ''

Обратите внимание, что .{0,300} часть регулярного выражения будет соответствовать по крайней мере0 символов и максимум 300 символов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...