You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dash DataTable中基于列表匹配的子串着色及回调实现

Dash DataTable子串着色与动态更新实现方案

核心解决思路

Dash DataTable原生不支持单元格内子串单独着色,因此需要通过HTML格式化单元格内容的方式实现:将匹配列表中的子串用带红色样式的<span>标签包裹,再配置表格渲染HTML内容。

1. 编写子串着色处理函数

先实现一个工具函数,负责将原始字符串中匹配的子串替换为带红色样式的HTML标签:

import re
from dash import html

def highlight_matches(raw_text, match_items):
    if not raw_text:
        return ""
    # 转义原始文本中的HTML特殊字符,避免解析异常
    escaped_text = html.escape(raw_text)
    # 遍历匹配列表,替换对应子串
    for item in match_items:
        # 转义匹配项中的正则特殊字符,确保精确匹配
        safe_pattern = re.compile(re.escape(item), re.IGNORECASE)
        escaped_text = safe_pattern.sub(
            f'<span style="color:red;font-weight:bold;">{item}</span>',
            escaped_text
        )
    return escaped_text

2. 初始化支持HTML渲染的DataTable

创建DataTable时,需将目标列(col1)的presentation设为html,并关闭escape,确保HTML标签被正确渲染:

import dash
from dash import Dash, dash_table, html, Input, Output, State
import pandas as pd

app = Dash(__name__)

# 示例原始数据
raw_df = pd.DataFrame({
    "col1": ["apple,banana,orange,grape", "banana,pear,apple", "orange,grape,mango"],
    "col2": [1, 2, 3]
})
# 初始匹配列表
initial_matches = ["apple", "orange"]

# 预处理数据:给col1添加着色标签
processed_df = raw_df.copy()
processed_df["col1"] = processed_df["col1"].apply(
    lambda x: highlight_matches(x, initial_matches)
)

app.layout = html.Div([
    # 动态修改匹配列表的输入控件
    html.Input(
        id="match-input",
        placeholder="输入匹配项,逗号分隔",
        value="apple,orange"
    ),
    html.Button("更新匹配规则", id="update-btn", style={"margin-left": "10px"}),
    # 配置好的DataTable
    dash_table.DataTable(
        id="color-table",
        data=processed_df.to_dict("records"),  # 转成records格式传入
        columns=[
            {
                "name": "col1",
                "id": "col1",
                "presentation": "html",
                "escape": False
            },
            {"name": "col2", "id": "col2"}
        ],
        style_cell={"textAlign": "left", "padding": "8px"}
    )
])

3. 回调实现动态更新

通过回调监听按钮点击,获取新的匹配列表,重新处理原始数据后更新表格:

@app.callback(
    Output("color-table", "data"),
    Input("update-btn", "n_clicks"),
    State("match-input", "value"),
    prevent_initial_call=False
)
def update_table_highlight(n_clicks, input_str):
    # 解析输入的匹配列表,去除空项和空格
    new_matches = [item.strip() for item in input_str.split(",") if item.strip()]
    # 重新处理原始数据
    updated_df = raw_df.copy()
    updated_df["col1"] = updated_df["col1"].apply(
        lambda x: highlight_matches(x, new_matches)
    )
    # 转成records格式返回,更新表格数据
    return updated_df.to_dict("records")

关于data.to_dict('records')的使用说明

  • 当你完成数据的HTML格式化后,调用df.to_dict('records')会将DataFrame的每一行转换为一个字典(键为列名,值为处理后的内容),这是Dash DataTable要求的data属性格式。
  • 直接将该结果赋值给DataTable的data参数,表格会自动渲染更新后的内容——因为我们已经配置了col1列支持HTML渲染,所以带样式的子串会正常显示红色。

关键注意事项

  • 必须用html.escape转义原始文本,避免特殊字符(如<、>)破坏HTML结构,同时防范XSS风险。
  • 匹配子串时用re.escape(item),确保匹配项中的正则特殊字符(如.、*)被当作普通字符处理,避免匹配异常。
  • 实际项目中建议用dcc.Store存储原始数据,避免在回调中重复定义,提升代码可维护性。

内容的提问来源于stack exchange,提问作者Mr.Slow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 01:25:23