需求来源于希望控制台(比如 PyCharm )可以输出彩色醒目的结果。
目录
1 Console codes
1.1 简介
Console codes 指的是在计算机终端或控制台中执行的命令或代码,通常用于直接与操作系统或特定程序进行交互。不同类型的 console codes 可以包括:
1.1.1 操作系统命令
例如,Windows 的 CMD 或 PowerShell,Linux 和 macOS 的终端(Terminal)。在这些控制台中输入命令可以直接与系统交互,例如:
- ls(列出当前目录的文件和文件夹,适用于 Linux/macOS)
- dir(列出当前目录的内容,适用于 Windows)
- cd(改变当前目录)
1.1.2 编程语言的控制台代码
很多编程语言都有交互式解释器或 REPL(Read-Eval-Print Loop),允许你在控制台中输入代码并立即运行。例如:
- Python 中的 print("Hello, world!")
- Node.js 中的 console.log("Hello, World!")
1.1.3 调试控制台命令
许多集成开发环境(IDE)或者浏览器的开发者工具中也有控制台,用于调试代码。例如,JavaScript 开发者常常使用浏览器的开发者工具控制台来执行 console.log() 以调试程序。
我们这里关注1.1.2,Console codes 提供了在终端中使用 ANSI 颜色的方法。
1.2 For Windows
来源:Use ANSI colors in the terminal - Windows CMD - SS64.com
How-to: Use ANSI colors in the terminal
ANSI colors are available by default in Windows version 1909 or newer. See below for older versions.
Specify the color codes in a batch file by ECHOing the foreground and/or background COLOR codes (from the following table) followed by the text to be formatted, followed by the ANSI default (Esc[0m) to reset the terminal back to the default colors.
These codes are the same as those used in a Unix/Linux/VT 100 terminal though the colors may be slightly different shades.
操作方法:在终端中使用 ANSI 颜色
默认情况下,ANSI 颜色在 Windows 版本 1909 或更高版本中可用。
通过在批处理文件中指定颜色代码,方法是 ECHO前景色和/或背景颜色代码(来自下表),后跟要格式化的文本,然后是 ANSI 默认值 (Esc[0m),以将终端重置回默认颜色。
这些代码与 Unix/Linux/VT 100 终端中使用的代码相同,尽管颜色的阴影可能略有不同。
1.2.1 ECHO前景色和/或背景颜色代码
Color | Foreground | Background | COLOR equivalent |
---|---|---|---|
Default | Esc[0m | ||
Black BLACK | Esc[30m | Esc[40m | 0 |
Red DARK_RED | Esc[31m | Esc[41m | 4 |
Green DARK_GREEN | Esc[32m | Esc[42m | 2 |
Yellow DARK_YELLOW | Esc[33m | Esc[43m | 6 |
Blue DARK_BLUE | Esc[34m | Esc[44m | 1 |
Magenta DARK_MAGENTA | Esc[35m | Esc[45m | 5 |
Cyan DARK_CYAN | Esc[36m | Esc[46m | 3 |
Light gray DARK_WHITE | Esc[37m | Esc[47m | 7 |
Dark gray BRIGHT_BLACK | Esc[90m | Esc[100m | 8 |
Light red BRIGHT_RED | Esc[91m | Esc[101m | C |
Light green BRIGHT_GREEN | Esc[92m | Esc[102m | A |
Light yellow BRIGHT_YELLOW | Esc[93m | Esc[103m | E |
Light blue BRIGHT_BLUE | Esc[94m | Esc[104m | 9 |
Light magenta BRIGHT_MAGENTA | Esc[95m | Esc[105m | D |
Light cyan BRIGHT_CYAN | Esc[96m | Esc[106m | B |
White WHITE | Esc[97m | Esc[107m | F |
Bold | Esc[1m | ||
Underline | Esc[4m | ||
No underline | Esc[24m | ||
Reverse text | Esc[7m | ||
Positive text (not reversed) | Esc[27m |
注: 上述中 Esc 需要使用转义字符来替换:\033。
1.3 For Linux
来源:console_codes(4) - Linux manual page (man7.org)
ECMA-48 Select Graphic Rendition
The ECMA-48 SGR sequence ESC [ parameters m sets display attributes. Several attributes can be set in the same sequence, separated by semicolons. An empty parameter (between semicolons or string initiat
ECMA-48 选择图形呈现
ECMA-48 SGR 序列 ESC [ 参数 m 设置显示属性。可以在同一序列中设置多个属性,以分号分隔。空参数(在分号或字符串之间)
1.3.1 Parameters
Param | Result |
0 | reset all attributes to their defaults |
1 | set bold |
2 | set half-bright (simulated with color on a color display) |
3 | set italic (since Linux 2.6.22 |
4 | set underscore (simulated with color on a color display) (the colors used to simulate dim or underline are set using ESC ] ...) |
5 | set blink |
7 | set reverse video |
10 | reset selected mapping, display control flag, and toggle meta flag (ECMA-48 says "primary font"). |
11 | select null mapping, set display control flag, reset toggle meta flag (ECMA-48 says "first alternate font"). |
12 | select null mapping, set display control flag, set toggle meta flag (ECMA-48 says "second alternate font"). The toggle meta flag causes the high bit of a byte to be toggled before the mapping table translation is done. |
21 | set underline done in many other terminals) |
22 | set normal intensity |
23 | italic off (since Linux 2.6.22) |
24 | underline off |
25 | blink off |
27 | reverse video off |
30 | set black foreground |
31 | set red foreground |
32 | set green foreground |
33 | set brown foreground |
34 | set blue foreground |
35 | set magenta foreground |
36 | set cyan foreground |
37 | set white foreground |
38 | 256/24-bit foreground color follows, shoehorned into 16 basic colors (before Linux 3.16: set underscore on, set default foreground color) |
39 | set default foreground color (before Linux 3.16: set underscore off, set default foreground color) |
40 | set black background |
41 | set red background |
42 | set green background |
43 | set brown background |
44 | set blue background |
45 | set magenta background |
46 | set cyan background |
47 | set white background |
48 | 256/24-bit background color follows, shoehorned into 8 basic colors |
49 | set default background color |
90..97 | set foreground to bright versions of 30..37 |
100..107 | set background, same as 40..47 (bright not supported) |
注:这个表中的参数可以与 1.2.1 结合一起参考。这里指示了可以同时配置多个参数。比如:
param_1 = '1' # set bold
param_2 = '2' # set half-bright (simulated with color on a color display)
param_3 = '3' # set italic (since Linux 2.6.22; simulated with color on a color display)
content = 'Hellow, World!'
print(f"\033[{param_1};{param_2};{param_3}m{content}\033[0m")
2 着色(coloring)
以 Python 为例,展示着色代码。简单起见,我们暂不考虑多个参数的情况。
import random
import re
def coloring(content: str, color: str=None) -> str:
"""
:param content: string to be colored
:param color: red, green, yellow, blue, purple, cyan, white, red_bg, green_bg, yellow_bg, blue_bg, purple_bg, cyan_bg, white_bg
:return:
"""
if color == 'None':
return content
colors = {
'red': '\033[31m',
'green': '\033[32m',
'yellow': '\033[33m',
'blue': '\033[34m',
'purple': '\033[35m',
'cyan': '\033[36m',
'white': '\033[37m',
'red_bg': '\033[41m',
'green_bg': '\033[42m',
'yellow_bg': '\033[43m',
'blue_bg': '\033[44m',
'purple_bg': '\033[45m',
'cyan_bg': '\033[46m',
'white_bg': '\033[47m',
}
if color is None:
while True:
color = random.choice(list(colors.keys()))
if color.endswith('_bg'):
continue
else:
break
return f'{colors[color]}{content}\033[0m'
这里定义了常见的前景色和背景色(对应于 1.3.1 中的 31-37 和 41-47),可根据需求增加。color 参数默认为 None,将在前景色中随机选择一个。用户可自定义对应的颜色。或,color=str('None') 时,表示不上色,即返回原文本。
3 褪色(decoloring)
有时需要将控制台的输出内容同时保存到文件中,比如 txt 文档。一般的编辑器不可可视化颜色,同时,增加的额外字符串会破坏原有的内容。于是,可自定义一个褪色函数。
def decoloring(content: str) -> str:
content = re.sub(r'\033\[\d+m', '', content)
content = re.sub(r'\033\[0m', '', content)
return content
功能比较直接,替换掉前缀 r'\033\[\d+m' 和后缀 r'\033\[0m' 字符串。需要注意的是,如果增加为多个参数时,需要适当调整正则匹配式。
4 使用
直接展示代码。
def main():
colorful = f"{coloring('Hello', 'red')}, {coloring('World')}!"
print(colorful)
monochrome = decoloring(colorful)
print(monochrome)
if __name__ == '__main__':
main()