我有一个基于正则表达式,自定义模板过滤器,找到并强调投入的搜索引擎,像谷歌关键字。例如,如果用户搜索“蛋糕”,我的过滤器将突出“蛋糕”“我刚吃了一个蛋糕。”下面是过滤器的代码:
@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
滤波器(围绕在搜索结果中的关键字,比如在谷歌显示文本)的代码:
@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)
我没有发现任何问题与您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}
将匹配ATLEAST 0 char和atmost 300个字符。