news 2026/9/18 11:20:38

Rich 高亮机制完全指南:自动语法高亮、自定义 Highlighter 与内置高亮器详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Rich 高亮机制完全指南:自动语法高亮、自定义 Highlighter 与内置高亮器详解

Rich 高亮机制完全指南:自动语法高亮、自定义 Highlighter 与内置高亮器详解

【免费下载链接】richRich is a Python library for rich text and beautiful formatting in the terminal.项目地址: https://gitcode.com/gh_mirrors/ri/rich

Rich 是一款用于在终端中生成富文本与精美格式的 Python 库,而文本高亮是它最直观、最常用的能力之一:当你用printlog输出内容时,Rich 会自动识别文本中的数字、字符串、布尔值、None、文件路径、URL、UUID 等模式并施加颜色样式,让日志和调试输出一目了然。本篇指南以 docs/source/highlighting.rst 为骨架,结合 rich/highlighter.py、rich/console.py、rich/text.py 等源码实现,系统讲解高亮的开关控制、自定义高亮器的两种写法(正则驱动与逐字符控制)、以及仓库内置的多个高亮器。读完后你将能熟练地为自己的终端输出定制专属高亮规则。

一、默认高亮:Rich 自动识别哪些模式

Rich 在渲染字符串时会自动对文本做高亮处理。以Console.print输出为例,默认情况下以下模式都会被识别并着色:

  • 数字:整数、浮点数、科学计数法、十六进制数;
  • 字符串:单引号 / 双引号 / 三引号包裹的文本;
  • 集合与括号[]{}()等括号符号;
  • 布尔值与 NoneTrueFalseNone
  • 路径与文件名:如/foo/bar/baz.py
  • URLhttps://http://ws://file://等协议开头的链接;
  • UUID:标准 8-4-4-4-12 十六进制格式;
  • 以及 IPv4、IPv6、MAC 地址(EUI-48 / EUI-64)、函数调用、省略号等更"小众"的模式。

这些规则集中定义在默认高亮器ReprHighlighter中,见 rich/highlighter.py。它把模式分成若干命名组,例如numberstrpathfilenameurluuidipv4ipv6bool_truenone等,再配合 rich/default_styles.py 中的默认样式表完成着色:

样式名默认效果
repr.number青色(cyan)加粗
repr.str绿色(green)
repr.bool_true亮绿(bright_green)斜体
repr.bool_false亮红(bright_red)斜体
repr.none洋红(magenta)斜体
repr.url亮蓝(bright_blue)下划线
repr.uuid亮黄(bright_yellow)
repr.path/repr.filename洋红 / 亮洋红
repr.ipv4/repr.ipv6亮绿加粗

二、高亮的开关控制:全局与局部

高亮默认开启,但你可以通过三种粒度进行控制。

2.1 在 print / log 上按次关闭

Console.printConsole.log上设置highlight=False,即可对本次调用禁用高亮:

from rich.console import Console console = Console() console.print("https://example.org is a URL") # URL 会被高亮 console.print("https://example.org is a URL", highlight=False) # 本次不高亮

2.2 在 Console 构造函数上全局关闭

Console(...)构造函数中设置highlight=False,则所有输出默认都不再高亮。查看 rich/console.py 的构造函数签名可以看到,highlight默认值为Truehighlighter默认为ReprHighlighter()

from rich.console import Console console = Console(highlight=False) console.print("2024-01-01 08:00:00") # 时间字符串不会被高亮

2.3 全局关闭后按需开启

highlight参数在 print / log 上的取值遵循"局部优先、未指定则回落全局"的逻辑。在 render_str 的实现 中可以看到判断方式:

highlight_enabled = highlight or (highlight is None and self._highlight)

也就是说,当传入highlight=True时强制开启;传入False时强制关闭;传入None(默认)时继承 Console 构造函数的全局设置。因此即使你在构造函数上关闭了高亮,仍然可以在个别 print / log 调用中传highlight=True选择性开启

from rich.console import Console console = Console(highlight=False) # 全局关闭 console.print("Send funds to money@example.org", highlight=True) # 本条强制开启

2.4 彻底关闭:NullHighlighter

除了用布尔开关,你还可以把高亮器显式替换为 NullHighlighter。它的highlight方法什么都不做("Nothing to do"),其文档字符串说明它"用于彻底禁用高亮":

from rich.console import Console from rich.highlighter import NullHighlighter console = Console(highlighter=NullHighlighter())

在源码内部,rich/console.py 还维护了一个模块级单例_null_highlighter,当构造 Console 时未显式传入highlighter或传入为空时使用;默认情况下则使用ReprHighlighter()(见 rich/console.py)。

三、自定义高亮器(一):RegexHighlighter 正则驱动

如果默认高亮无法满足需求,最便捷的方式是继承 RegexHighlighter:它接收一组正则表达式,凡是匹配的文本都会被施加样式。原文档给出了一个识别邮箱地址的经典例子,这也是仓库 examples/highlighter.py 中的完整示例:

from rich.console import Console from rich.highlighter import RegexHighlighter from rich.theme import Theme class EmailHighlighter(RegexHighlighter): """Apply style to anything that looks like an email.""" base_style = "example." highlights = [r"(?P<email>[\w-]+@([\w-]+\.)+[\w-]+)"] theme = Theme({"example.email": "bold magenta"}) console = Console(highlighter=EmailHighlighter(), theme=theme) console.print("Send funds to money@example.org")

3.1 highlights 与 base_style 的配合机制

RegexHighlighter只需声明两个类变量:

  • highlights:一个正则表达式列表。每个正则表达式的命名组(?P<name>...))会被翻译为样式名;
  • base_style:一个前缀字符串。任何匹配组的样式名都会被加上此前缀。

上例中,正则的命名组为emailbase_style"example.",于是匹配到的邮箱文本最终应用样式"example.email",而该样式恰好定义在自定义Theme中("bold magenta",加粗洋红)。

从源码看,RegexHighlighter.highlight的实现非常精简,见 rich/highlighter.py:

def highlight(self, text: Text) -> None: highlight_regex = text.highlight_regex for re_highlight in self.highlights: highlight_regex(re_highlight, style_prefix=self.base_style)

它遍历highlights中的每个正则,委托给Text.highlight_regex。真正的样式落地发生在 rich/text.py:highlight_regex会在纯文本上执行finditer匹配,然后把每个命名组的起止位置转换为Span(start, end, f"{style_prefix}{name}")追加到文本的 span 列表中。也就是说,命名组名 + base_style 前缀 = 最终样式名,这是整个 RegexHighlighter 机制的核心约定。

3.2 挂载到 Console 与局部调用

把高亮器挂在Console(highlighter=...)上,之后所有 print 输出(在开启高亮的前提下)都会经过它。另一种更细粒度的用法是把高亮器实例当作可调用对象,手动处理某段文本后再交给 console 输出:

from rich.console import Console from rich.theme import Theme # 复用上一节的 EmailHighlighter 定义 console = Console(theme=theme) highlight_emails = EmailHighlighter() console.print(highlight_emails("Send funds to money@example.org"))

这是因为 Highlighter.call接受strText:若传入字符串会先包装为Text,若传入Text则会复制一份再就地高亮(避免污染原对象),最后返回带样式的高亮文本。传入其他类型会抛出TypeError

四、自定义高亮器(二):继承 Highlighter 抽象基类

RegexHighlighter虽强,但终究受限于"正则 + 命名组"这一模式。如果你想完全自定义高亮逻辑,可以直接继承抽象基类 Highlighter。它只要求实现一个方法:

class Highlighter(ABC): def __call__(self, text): ... # 已实现:处理 str/Text 输入 @abstractmethod def highlight(self, text: Text) -> None: """Apply highlighting in place to text."""

highlight接收一个 Text 对象并就地修改。原文档给出了一个"彩虹高亮器"的例子——给每个字符随机分配一种颜色:

from random import randint from rich import print from rich.highlighter import Highlighter class RainbowHighlighter(Highlighter): def highlight(self, text): for index in range(len(text)): text.stylize(f"color({randint(16, 255)})", index, index + 1) rainbow = RainbowHighlighter() print(rainbow("I must not fear. Fear is the mind-killer."))

这里用到的Text.stylize(style, start, end)在 rich/text.py 中实现:它把Span(start, end, style)追加到文本的 span 列表,并支持负索引与越界保护。f"color({randint(16, 255)})"会解析为 16–255 号调色板颜色,从而让每个字符呈现不同颜色。这个例子展示了自定义高亮器的本质——在 Text 对象上按任意规则附加 span,样式系统会负责最终的渲染。

五、内置高亮器一览

rich.highlighter模块中预置了以下高亮器,可直接导入使用。

5.1 ReprHighlighter(默认)

ReprHighlighter的文档描述为"高亮__repr__方法典型产出的文本",它是 Console 的默认高亮器。其规则覆盖范围最广,包含:

  • 标签结构(<tag_name>...</tag_name>);
  • 属性名与属性值(key=value);
  • 括号[]{}()
  • IPv4 / IPv6 / EUI-48 / EUI-64 地址;
  • UUID;
  • 函数调用(name();
  • True/False/None
  • 复数、普通数字(含十六进制);
  • 路径与文件名;
  • 字符串字面量;
  • URL。

5.2 JSONHighlighter

JSONHighlighter(见 rich/highlighter.py)用于高亮 JSON 文本,基础样式前缀为"json.",覆盖括号、true/false/null、数字与字符串。它还在父类正则高亮的基础上额外重写了highlight:通过re.finditer扫描字符串字面量,若其后(跳过空白)紧跟着冒号:,则判定该字符串为 JSON 键,追加json.key样式。默认样式表在 rich/default_styles.py 中定义:

样式名默认效果
json.brace加粗
json.bool_true亮绿斜体
json.bool_false亮红斜体
json.null洋红斜体
json.number青色加粗
json.str绿色
json.key蓝色加粗

5.3 ISO8601Highlighter

ISO8601Highlighter(见 rich/highlighter.py)专用于高亮 ISO 8601 日期时间字符串,样式前缀为"iso8601."。它的规则非常细致,覆盖了年月、日期、星期、时间、时区以及带时区的日期时间、XML Schema 的date/time/dateTime类型等十余种变体。默认样式为iso8601.date(蓝色)、iso8601.time(洋红)、iso8601.timezone(黄色),见 rich/default_styles.py。

5.4 NullHighlighter

见上文 2.4 节,用于彻底禁用高亮。

六、源码视角:高亮在渲染链路中如何生效

理解整条调用链有助于你在复杂场景中定位高亮行为。以console.print("...")为例:

  1. Console.print收集渲染对象,把highlight参数传入渲染选项(见 rich/console.py);
  2. 字符串最终进入Console.render_str,其中计算highlight_enabled(局部参数优先,否则取构造函数默认值);
  3. 若启用高亮,取highlighter or self.highlighter,调用_highlighter(str(rich_text)),得到高亮后的Text再拷贝样式回原文本(rich/console.py);
  4. RegexHighlighter内部调用Text.highlight_regex,把每个正则命名组的区间转为Span
  5. 渲染阶段,Text的 span 叠加出最终样式(参考 rich/text.py 的get_style_at_offset:按字符偏移合并所有覆盖该位置的 span 样式)。

log方法同样接收highlight参数(默认None,回落全局设置),见 rich/console.py,因此在日志输出上也可以独立控制高亮。

七、配套示例与测试

  • 示例:examples/highlighter.py 提供了与本文 3.1 节完全一致的EmailHighlighter完整可运行代码;examples/log.py、examples/table.py 等示例也能直观看到默认高亮在真实输出中的效果。
  • 测试:tests/test_highlighter.py 覆盖了自定义高亮器对非法类型抛错(test_wrong_type)、highlight_regex的 span 产出(test_highlight_regex)、JSON 高亮在有无缩进及纯字符串场景下的行为(test_highlight_json_*),以及 ISO 8601 高亮的正则匹配(test_highlight_iso8601_regex)。阅读这些测试可以快速理解高亮器的输入输出契约。
  • 样式表:rich/default_styles.py 集中定义了repr.*json.*iso8601.*三组高亮默认样式,修改或补充样式时可在此查找参考。
  • 主题机制:自定义高亮器常与Theme配合使用,主题的完整说明见 docs/source/theme.rst。

八、小结:高亮器的选型建议

需求推荐方案
开箱即用的默认高亮直接使用 Console 默认的ReprHighlighter
高亮某种特定模式(邮箱、ID、日志关键字等)继承RegexHighlighter,用命名组 +base_style+ 自定义Theme
高亮 JSON / ISO 8601 时间字符串直接用内置的JSONHighlighter/ISO8601Highlighter
完全自定义的高亮算法继承Highlighter,重写highlight(text),在Text上按需stylize
需要关闭高亮highlight=False(print/log 或 Console 构造函数),或挂载NullHighlighter

掌握高亮机制后,无论是日志着色、数据展示还是 REPL 风格的输出,你都能用最少的代码让终端文本变得层次分明、易于阅读。

【免费下载链接】richRich is a Python library for rich text and beautiful formatting in the terminal.项目地址: https://gitcode.com/gh_mirrors/ri/rich

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 11:20:28

数据库系统原理实战:从关系模型到ACID落地

1. 这不是教科书笔记&#xff0c;而是一份“能跑通、能排错、能讲清楚”的数据库系统原理实战手记我带过三届数据库课程设计&#xff0c;也给金融、制造、政务类客户做过十多个数据库架构优化项目。每次新人一上来就翻《数据库系统概论》第六版&#xff0c;划重点、背定义、抄E…

作者头像 李华
网站建设 2026/9/18 11:20:20

洪水调节课程设计:从水量平衡到水库调洪演算全流程解析

简介&#xff1a;一份面向水利水电工程专业学生的洪水调节课程设计参考文档&#xff0c;完整展示三峡大学该课程设计的任务要求与计算思路。内容涵盖设计目的、工程基本资料、洪水标准确定&#xff0c;以及列表试算法、半图解法推求下泄流量、库容与水位变化过程的详细流程&…

作者头像 李华
网站建设 2026/9/18 11:20:02

MindSpore Transformers训练实时监控实战:Callback+WebSocket+ECharts

前阵子我调一个 Deformable DETR 的微调实验&#xff0c;模型用 MindSpore Transformers 套件加载&#xff0c;睡前看了一眼 loss 还在 0.8 附近&#xff0c;心里想着“还行&#xff0c;明早起来应该能收敛”。结果第二天打开终端&#xff0c;屏幕上一行刺眼的 loss: nan&#…

作者头像 李华
网站建设 2026/9/18 11:19:40

Highcharts表格直驱可视化:HTML Table自动转图表教程

1. 为什么这个标题值得你花15分钟认真读完Highcharts 实战&#xff5c;HTML表格数据源自动可视化开发教程&#xff08;附Demo&#xff09;——这行字里藏着三个关键信号&#xff1a;Highcharts是工业级图表库的“老司机”&#xff0c;不是玩具级轮子&#xff1b;HTML表格数据源…

作者头像 李华
网站建设 2026/9/18 11:17:58

【ComfyUI】QwenImageEdit 基础图生图

今天展示的案例是一个基于 Qwen-Image 编辑功能的 ComfyUI 工作流。该工作流围绕图像编辑展开,通过加载扩散模型、文本编码器、VAE 模块以及 LoRA 适配器,结合输入图像与文本提示,实现对图像中元素的精准移除与增强效果。 整体设计不仅保证了画面质量,也通过采样器与归一化…

作者头像 李华
网站建设 2026/9/18 11:17:26

【ComfyUI】OmniGen2 基础图生图

今天展示的案例是一个基于 ComfyUI 的 Omnigen2 图生图工作流,通过输入原始图像与文本提示词,结合噪声生成、潜空间参考以及双重条件引导的机制,实现了透明晶体质感的人物再创作效果。 整个流程以清晰的阶段设计串联,从模型加载、图像输入、文本编码到采样生成与解码输出,…

作者头像 李华