简体   繁体   English

如何解析 Linux 终端颜色代码?

[英]How can I parse Linux terminal colour codes?

I'm trying to display coloured text form a file in a curses python app.我正在尝试在curses python 应用程序中显示文件中的彩色文本。 The file contains 24 bit colour escape codes such as: ^[[48;2;255;255;255m^[[38;2;255;255;255mA .该文件包含 24 位颜色转义码,例如: ^[[48;2;255;255;255m^[[38;2;255;255;255mA I need to loop through the file and generate a list of tuples, containing tuples like so: ((background: r, g, b), (foreground: r, g, b), char) .我需要遍历文件并生成元组列表,其中包含如下元组: ((background: r, g, b), (foreground: r, g, b), char) Here is the code I have tried so far.这是我到目前为止尝试过的代码。 It tries to find all the 0x27 bytes and parse them, however it does not seem to work, and not only that it is not particularly safe/scalable/maintainable.它试图找到所有 0x27 字节并解析它们,但它似乎不起作用,不仅因为它不是特别安全/可扩展/可维护。 How can I parse the colour codes in a file like this?我如何解析这样的文件中的颜色代码? Is there a library?有图书馆吗? How can I improve this code, if there is no library?如果没有图书馆,我该如何改进这段代码?

def read_until(char, data, pos):
    """read from a bytes-like object starting at `pos` until the target character is found"""
    start = pos
    while data[pos] != char: pos += 1
    return data[start:pos], pos

def makeData(data):
    assert type(data) == bytes

    out = []
    pos = 0
    bg = (0, 0, 0)
    fg = (255, 255, 255)

    while pos < len(data):
        if data[pos] == 27: #start of the escape sequence
            pos += 2 #+2 to ignore the `[` char
            if data[pos:pos + 2] == b"0m": #reset character, just ignore it
                continue
            first_num, pos = read_until(ord(";"), data, pos)
            second_num, pos = read_until(ord(";"), data, pos + 1) #+ 1 for the `;` char

            r, pos = read_until(ord(";"), data, pos + 1)
            g, pos = read_until(ord(";"), data, pos + 1)
            b, pos = read_until(ord("m"), data, pos + 1)
            r = int(r)
            g = int(g)
            b = int(b)
            pos += 1 #skip last `m` char
            if first_num == b"48": #48 means foreground
                fg = (r, g, b)
            elif first_num == b"38": #38 means background
                bg = (r, g, b)
        else:
            out.append((fg, bg, chr(data[pos]))) #use current fg and bg colours with char
            pos += 1
    return out

with open("file.txt", "rb") as f:
    print("".join([chr(i[2]) for i in makeData(f.read())])) #print without colour codes, to test

You can use regular expression to parse the data:您可以使用正则表达式来解析数据:

import re
with open("file.txt") as f:
    result = re.findall(r'\x1b\[48;2;(\d+);(\d+);(\d+)m\x1b\[38;2;(\d+);(\d+);(\d+)m(.)', f.read())
    print(result)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM