想要实现和百度搜索一样的输入的关键字标红

想要实现和百度搜索一样的输入的关键字标红

目前的代码为:

{% block main_body %}
    <div class = "container">
        <div class = "row">
            <div class = "col-md-8 col-mid-offset-2">
                {% if search_word == '' %}
                    <h3>您没有搜索任何内容。h3>
                    <hr>
                    <p>您可以尝试输入点什么, 例如:<a href="/search/?wd=浙江民营企业发展大厦">浙江民营企业发展大厦a>p>
                {% else %}
                    <h5 style =" color: dimgrey ">搜索"{{ search_word }}", 共找到{{ search_result_count }}个结果h5>
                        {% for vo in page_of_search %}
                        <hr>
                            <h4 class="entry-title" style =" color: mediumblue"><a href="{% url vo.name %}"><u>{{ vo.name }}u>a>h4>
                            <p class="fa fa-map-marker"> 地址 :{{ vo.address }}p>
                        {% empty %}
                        <p>未找到要搜索的目标p>
                        {% endfor %}
                {% endif %}
            div>
        div>
        <div class = "row">
            <ul class="pagination pagination-sm no-margin pull-right">
            <li><a href="{% url 'search' %}?wd={{ search_word }}&page= 1">首页a>li>
            {% if page_of_search.has_previous %}
                <li><a class = "btn btn-default" href = "{% url 'search' %}?wd={{ search_word }}&page={{ page_of_search.previous_page_number }}">上一页a>li>
            {% else %}
                <li><a class = "btn btn-default" href = "{% url 'search' %}?wd={{ search_word }}&page= 1">上一页a>li>
            {% endif %}
            {% for p in plist %}
                    <li {% if p == page_of_search.number%}class="active" {% endif %}><a href="{% url 'search' %}?wd={{ search_word }}&page={{ p }}">{{p}}a>li>
            {% endfor %}
            {% if page_of_search.has_next %}
                <li><a class = "btn btn-default" href = "{% url 'search' %}?wd={{ search_word }}&page={{ page_of_search.next_page_number }}">下一页a>li>
            {% else %}
                <li><a class = "btn btn-default" href = "{% url 'search' %}?wd={{ search_word }}&page= {{ maxpages }}">下一页a>li>
            {% endif %}
            <li><a href="{% url 'search' %}?wd={{ search_word }}&page= {{ maxpages }}">尾页a>li>
            ul>
        div>
    div>

{% endblock %}
def search(request):
   search_word = request.GET.get('wd', '')
   if search_word == '':
       building_result = Building.objects.filter(name__contains=search_word)
       coperation_result = Corporation.objects.filter(name__contains=search_word)
   else:
     word_list = jieba.lcut(search_word, cut_all=True)
     pattern = ''
     for word in word_list:
       pattern += '(?=.*' + word + ')'
     building_result = Building.objects.filter(Q(name__iregex=pattern) | Q(address__iregex=pattern))
     coperation_result = Corporation.objects.filter(Q(name__iregex=pattern) | Q(address__iregex=pattern))

   tmp_content_list = set()
   if building_result:
       tmp_content_list = set(building_result)

   # 最后将符合条件的文章标题模型和文章内容模型合并返回
   info_list = set()
   if coperation_result:
       info_list = set(coperation_result)

   # 在从文章标题模型中查找出最终汇总的模型返回
   search_result_set = info_list.union(tmp_content_list)
   search_result = list(search_result_set)

   #分页
   page = Paginator(search_result, 10)  # 以每页10条数据分页
   page_num = request.GET.get('page',1)
   page_of_search = page.get_page(page_num)
   maxpages = page.num_pages  # 获取最大页数

   plist = page.page_range  # 获取页码列表信息

   context = {'search_word':search_word,  'search_result':search_result,'search_result_count':len(search_result),'plist':plist,
              'page_of_search':page_of_search,'maxpages':maxpages,}
   return render(request, 'web/search.html',context)


目前的效果:

img


想要的效果:

img

麻烦给具体步骤或者代码,谢谢

可以使用 Django 自带的 safe 过滤器和正则表达式来实现搜索关键词标红的效果。具体实现如下:

1.在模板中导入 re 模块。

{% load static %}
{% load humanize %}
{% load mytags %}
{% load myfilters %}
{% load mathfilters %}
{% load bootstrap3 %}

{% load staticfiles %}
{% load crispy_forms_tags %}

{% load i18n %}
{% load tz %}
{% load re %}

2.使用正则表达式来匹配搜索关键词,并用 span 标签将其包裹起来。

<h4 class="entry-title" style =" color: mediumblue"><a href="{% url vo.name %}"><u>{{ vo.name|safe|re_sub:search_word|safe }}</u></a></h4>

其中,re_sub 是一个自定义的模板过滤器,其代码如下:

import re

from django import template

register = template.Library()

@register.filter
def re_sub(value, arg):
    """
    Replace all occurrences of the search string (arg) in the given string (value)
    with a span tag that highlights the matched string.
    """
    return re.sub(re.escape(arg), '<span class="highlight">\g<0></span>', value, flags=re.IGNORECASE)

这个过滤器会将所有匹配到的搜索关键词用 span 标签包裹起来,并添加一个 highlight 的 CSS 类来实现高亮效果。你可以根据需要修改这个 CSS 类的样式。

回答不易,希望对你有用,能够采纳。

首先,需要分析百度搜索的关键字标红功能,其实就是对输入的关键字进行字符串处理,以及HTML标签的解析;

然后,需要使用正则表达式,来获取输入的关键字,然后将关键字用HTML标签 等来包裹起来;

接着,使用浏览器的innerHTML方法,将获取到的HTML标签字符串渲染出来,完成输入的关键字标红功能。

该回答引用GPTᴼᴾᴱᴺᴬᴵ
你可以使用 re 模块对匹配到的搜索关键词进行替换,并添加标红的样式。具体代码如下:

import re

def search(request):
   search_word = request.GET.get('wd', '')
   if search_word == '':
       building_result = Building.objects.filter(name__contains=search_word)
       coperation_result = Corporation.objects.filter(name__contains=search_word)
   else:
     word_list = jieba.lcut(search_word, cut_all=True)
     pattern = ''
     for word in word_list:
       pattern += '(?=.*' + word + ')'
     building_result = Building.objects.filter(Q(name__iregex=pattern) | Q(address__iregex=pattern))
     coperation_result = Corporation.objects.filter(Q(name__iregex=pattern) | Q(address__iregex=pattern))

   tmp_content_list = set()
   if building_result:
       tmp_content_list = set(building_result)

   # 最后将符合条件的文章标题模型和文章内容模型合并返回
   info_list = set()
   if coperation_result:
       info_list = set(coperation_result)

   # 在从文章标题模型中查找出最终汇总的模型返回
   search_result_set = info_list.union(tmp_content_list)
   search_result = list(search_result_set)

   # 分页
   page = Paginator(search_result, 10)  # 以每页10条数据分页
   page_num = request.GET.get('page',1)
   page_of_search = page.get_page(page_num)
   maxpages = page.num_pages  # 获取最大页数

   plist = page.page_range  # 获取页码列表信息

   # 关键词标红
   for result in search_result:
       for word in word_list:
           result.name = re.sub(word, f'<span style="color:red">{word}</span>', result.name)
           result.address = re.sub(word, f'<span style="color:red">{word}</span>', result.address)

   context = {'search_word':search_word,  'search_result':search_result,'search_result_count':len(search_result),'plist':plist,
              'page_of_search':page_of_search,'maxpages':maxpages,}
   return render(request, 'web/search.html',context)


这样可以把搜索结果中匹配到的关键词标红显示。在 HTML 模板中需要使用 safe 过滤器,以保留 HTML 标签。

参考GPT和自己的思路,要实现在搜索结果中将关键词标记为红色,可以使用 HTML 标签 mark 包围关键词,并在 CSS 样式中设置红色。可以通过使用 Django 自带的 safe 过滤器来避免 HTML 标签被转义,以便在搜索结果中正常显示标记。

以下是一个修改后的代码示例:

{% block main_body %}
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-mid-offset-2">
                {% if search_word == '' %}
                    <h3>您没有搜索任何内容。</h3>
                    <hr>
                    <p>您可以尝试输入点什么,例如:<a href="/search/?wd=浙江民营企业发展大厦">浙江民营企业发展大厦</a></p>
                {% else %}
                    <h5 style="color: dimgrey">搜索"{{ search_word }}", 共找到{{ search_result_count }}个结果</h5>
                    {% for vo in page_of_search %}
                        <hr>
                        <h4 class="entry-title" style="color: mediumblue"><a href="{% url vo.name %}"><u>{{ vo.name|safe|highlight:search_word }}</u></a></h4>
                        <p class="fa fa-map-marker"> 地址:{{ vo.address|safe|highlight:search_word }}</p>
                    {% empty %}
                        <p>未找到要搜索的目标</p>
                    {% endfor %}
                {% endif %}
            </div>
        </div>
        <div class="row">
            <ul class="pagination pagination-sm no-margin pull-right">
                <li><a href="{% url 'search' %}?wd={{ search_word }}&page=1">首页</a></li>
                {% if page_of_search.has_previous %}
                    <li><a class="btn btn-default" href="{% url 'search' %}?wd={{ search_word }}&page={{ page_of_search.previous_page_number }}">上一页</a></li>
                {% else %}
                    <li><a class="btn btn-default" href="{% url 'search' %}?wd={{ search_word }}&page=1">上一页</a></li>
                {% endif %}
                {% for p in plist %}
                    <li {% if p == page_of_search.number %}class="active" {% endif %}><a href="{% url 'search' %}?wd={{ search_word }}&page={{ p }}">{{ p }}</a></li>
                {% endfor %}
                {% if page_of_search.has_next %}
                    <li><a class="btn btn-default" href="{% url 'search' %}?wd={{ search_word }}&page={{ page_of_search.next_page_number }}">下一页</a></li>
                {% else %}
                    <li><a class="btn btn-default" href="{% url 'search' %}?wd={{ search_word }}&page={{ maxpages }}">下一页</a></li>
                {% endif %}
                <li><a href="{% url 'search' %}?wd={{ search_word }}&page={{ maxpages }}">尾页</a></li>
            </ul>
        </div>
    </div>
{% endblock %}

要实现和百度搜索一样的输入的关键字标红,您可以按照以下步骤进行操作:

在模板中使用safe过滤器将搜索结果中的名称和地址等文本包裹在一个span标签中,并添加一个名为highlight的CSS类,如下所示:

<h4 class="entry-title" style="color: mediumblue"><a href="{% url vo.name %}"><u><span class="highlight">{{ vo.name|safe }}</span></u></a></h4>
<p class="fa fa-map-marker"> 地址:<span class="highlight">{{ vo.address|safe }}</span></p>

在CSS文件中定义一个名为highlight的类,指定文本的背景颜色为黄色(或其他您喜欢的颜色),如下所示:

.highlight {
  background-color: yellow;
}

在Python代码中使用re.sub()函数将搜索词替换为带有highlight类的文本,如下所示:


import re
...
for vo in page_of_search:
    # 将搜索词替换为带有highlight类的文本
    name = re.sub(search_word, f'<span class="highlight">{search_word}</span>', vo.name, flags=re.IGNORECASE)
    address = re.sub(search_word, f'<span class="highlight">{search_word}</span>', vo.address, flags=re.IGNORECASE)
    # 渲染模板时使用替换后的文本
    context['search_result'].append({'name': name, 'address': address})

注意:在使用re.sub()函数替换文本时,为了匹配大小写不敏感的搜索词,需要使用flags=re.IGNORECASE参数。


以下是实现输入的关键字标红的代码示例:

{% block main_body %}
<div class = "container">
<div class = "row">
<div class = "col-md-8 col-mid-offset-2">
{% if search_word == '' %}
<h3>搜索任何内容。</h3>
<hr>
<p>尝试输入点什么, 例如:<a href="/search/?wd="></a></p>
{% else %}
<h5 style =" color: dimgrey ">搜索"{{ search_word }}", 共找到{{ search_result_count }}个结果</h5>
{% for vo in page_of_search %}
<hr>
<h4 class="entry-title" style =" color: mediumblue"><a href="{% url vo.name %}"><u>{{ vo.name|highlight:search_word }}</u></a></h4>
<p class="fa fa-map-marker"> 地址 :{{ vo.address|highlight:search_word }}</p>
{% empty %}
<p>未找到要搜索的目标</p>
{% endfor %}
{% endif %}
</div>
</div>
<div class = "row">
<ul class="pagination pagination-sm no-margin pull-right">
<li><a href="{% url 'search' %}?wd={{ search_word }}&page= 1">首页</a></li>
{% if page_of_search.has_previous %}
<li><a class = "btn btn-default" href = "{% url 'search' %}?wd={{ search_word }}&page={{ page_of_search.previous_page_number }}">上一页</a></li>
{% else %}
<li><a class = "btn btn-default" href = "{% url 'search' %}?wd={{ search_word }}&page= 1">上一页</a></li>
{% endif %}
{% for p in plist %}
<li {% if p == page_of_search.number%}class="active" {% endif %}><a href="{% url 'search' %}?wd={{ search_word }}&page={{ p }}">{{p}}</a></li>
{% endfor %}
{% if page_of_search.has_next %}
<li><a class = "btn btn-default" href = "{% url 'search' %}?wd={{ search_word }}&page={{ page_of_search.next_page_number }}">下一页</a></li>
{% else %}
<li><a class = "btn btn-default" href = "{% url 'search' %}?wd={{ search_word }}&page= {{ maxpages }}">下一页</a></li>
{% endif %}
<li><a href="{% url 'search' %}?wd={{ search_word }}&page= {{ maxpages }}">尾页</a></li>
</ul>
</div>
</div>

{% endblock %}

在模板中,我们对搜索结果的名称和地址应用了一个名为“highlight”的自定义模板标签。这个标签的作用是在匹配搜索关键字时,将其用<span>标签包围,以便通过CSS样式来高亮显示。

以下是自定义“highlight”标签的代码:

from django import template

register = template.Library()

@register.filter
def highlight(text, search):
highlighted = text.replace(search)

下一步是对搜索结果中的关键词进行标红。可以使用Python的正则表达式来实现这个功能。具体步骤如下:

将搜索词分词并用空格拼接成正则表达式的模式。
遍历搜索结果列表中的每一个结果对象,将结果对象中的name和address属性中的匹配搜索词的部分用html标签将其标红。
将标红后的结果对象添加到新的列表中,最终将新列表作为搜索结果返回给前端。


import re

def search(request):
   search_word = request.GET.get('wd', '')
   if search_word == '':
       building_result = Building.objects.filter(name__contains=search_word)
       coperation_result = Corporation.objects.filter(name__contains=search_word)
   else:
     word_list = jieba.lcut(search_word, cut_all=True)
     pattern = ''
     for word in word_list:
       pattern += '(?=.*' + word + ')'
     building_result = Building.objects.filter(Q(name__iregex=pattern) | Q(address__iregex=pattern))
     coperation_result = Corporation.objects.filter(Q(name__iregex=pattern) | Q(address__iregex=pattern))

   tmp_content_list = set()
   if building_result:
       tmp_content_list = set(building_result)

   # 最后将符合条件的文章标题模型和文章内容模型合并返回
   info_list = set()
   if coperation_result:
       info_list = set(coperation_result)

   # 在从文章标题模型中查找出最终汇总的模型返回
   search_result_set = info_list.union(tmp_content_list)
   search_result = list(search_result_set)

   # 对搜索结果中的关键词进行标红
   if search_word:
       pattern = '|'.join(word_list)
       for result in search_result:
           result.name = re.sub(pattern, lambda x: '<span style="color:red">' + x.group() + '</span>', result.name)
           result.address = re.sub(pattern, lambda x: '<span style="color:red">' + x.group() + '</span>', result.address)

   #分页
   page = Paginator(search_result, 10)  # 以每页10条数据分页
   page_num = request.GET.get('page',1)
   page_of_search = page.get_page(page_num)
   maxpages = page.num_pages  # 获取最大页数

   plist = page.page_range  # 获取页码列表信息

   context = {'search_word':search_word,  'search_result':search_result,'search_result_count':len(search_result),'plist':plist,
              'page_of_search':page_of_search,'maxpages':maxpages,}
   return render(request, 'web/search.html',context)

需要注意的是,在前端页面中需要使用safe过滤器来将标红后的HTML代码正常显示,例如:


<h4 class="entry-title" style="color: mediumblue"><a href="{% url vo.name %}">{{ vo.name|safe }}</a></h4>
<p class="fa fa-map-marker"> 地址:{{ vo.address|safe }}</p>

最简单直接的可以直接用一个replace把内容替换关键字为

```

<span class="red"》关键字《/span>

```然后在css里设置样式就好了

您可以使用 Django 内置的 highlight 模板标签来高亮显示搜索关键字

{% block main_body %}
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-mid-offset-2">
                {% if search_word == '' %}
                    <h3>您没有搜索任何内容。</h3>
                    <hr>
                    <p>您可以尝试输入点什么,例如:<a href="/search/?wd=浙江民营企业发展大厦">浙江民营企业发展大厦</a></p>
                {% else %}
                    <h5 style="color: dimgrey">搜索"{{ search_word }}", 共找到{{ search_result_count }}个结果</h5>
                    {% for vo in page_of_search %}
                        <hr>
                        <h4 class="entry-title" style="color: mediumblue">
                            <a href="{% url vo.name %}">
                                <u>{{ vo.name|highlight:search_word }}</u>
                            </a>
                        </h4>
                        <p class="fa fa-map-marker"> 地址:{{ vo.address|highlight:search_word }}</p>
                    {% empty %}
                        <p>未找到要搜索的目标</p>
                    {% endfor %}
                {% endif %}
            </div>
        </div>
        <div class="row">
            <ul class="pagination pagination-sm no-margin pull-right">
                <li><a href="{% url 'search' %}?wd={{ search_word }}&page=1">首页</a></li>
                {% if page_of_search.has_previous %}
                    <li>
                        <a class="btn btn-default" href="{% url 'search' %}?wd={{ search_word }}&page={{ page_of_search.previous_page_number }}">
                            上一页
                        </a>
                    </li>
                {% else %}
                    <li>
                        <a class="btn btn-default" href="{% url 'search' %}?wd={{ search_word }}&page=1">
                            上一页
                        </a>
                    </li>
                {% endif %}
                {% for p in plist %}
                    <li {% if p == page_of_search.number%}class="active" {% endif %}>
                        <a href="{% url 'search' %}?wd={{ search_word }}&page={{ p }}">{{ p }}</a>
                    </li>
                {% endfor %}
                {% if page_of_search.has_next %}
                    <li>
                        <a class="btn btn-default" href="{% url 'search' %}?wd={{ search_word }}&page={{ page_of_search.next_page_number }}">
                            下一页
                        </a>
                    </li>
                {% else %}
                    <li>
                        <a class="btn btn-default" href="{% url 'search' %}?wd={{ search_word }}&page={{ maxpages }}">
                            下一页
                        </a>
                    </li>
                {% endif %}
                <li><a href="{% url 'search' %}?wd={{ search_word }}&page={{ maxpages }}">尾页</a></li>
            </ul>
        </div>
    </div>
{% endblock %}



上述模板代码中,highlight 过滤器将使用搜索关键字高亮显示搜索结果页面中的名称和地址。